首页 > 其他分享 >北大OJ_1010题:STAMPS

北大OJ_1010题:STAMPS

时间:2022-12-07 17:34:00浏览次数:34  
标签:nCurMaxValue OJ int nCurStampCount ++ nCurTypeCount STAMPS gResultHelper 1010


#include <iostream>
#include <vector>
#include <algorithm>


using namespace std;


typedef vector<int> IntArray;

#define MAX_STAMP_N 4 //最大邮票数
#define MAX_TYPE_N 25 //最大邮票种类数25

struct tagResultHelper
{
int nCurTypeCount; //当前种类数
int nCurStampCount; //当前邮票数
int nCurMaxValue; //当前最大面额

int mResultSets[MAX_STAMP_N]; //当前结果集(始终保存最优的结果集)
bool bTieFlag; //tie标记
};

tagResultHelper gResultHelper; //结果集合辅助变量
int gStampArray[MAX_TYPE_N]; //邮票种类数组(保存每种面值)
int gTotalTypeCount; //总的邮票种类数



//得到最大值
int GetMaxValue( int mIntArray[MAX_STAMP_N], int nCurCount )
{
int nMax = -1;
for( int i = 0; i < nCurCount; ++i )
{
if ( mIntArray[i] > nMax )
{
nMax = mIntArray[i];
}
}

return nMax;
}




//更新最优解
void UpdateBestResult( int nCurTypeCount, int nCurMaxValue, int nCurStampCount,
int mIntArray[MAX_STAMP_N] )
{
//种类多于当前的,加入
if ( nCurTypeCount > gResultHelper.nCurTypeCount )
{
gResultHelper.nCurTypeCount = nCurTypeCount;
gResultHelper.nCurStampCount = nCurStampCount;
gResultHelper.nCurMaxValue = nCurMaxValue;

//更新结果
gResultHelper.bTieFlag = false;//重置tie标记
for( int i = 0; i < nCurStampCount; ++i ) gResultHelper.mResultSets[i]=mIntArray[i];

}
//种类等于当前的
else if ( nCurTypeCount == gResultHelper.nCurTypeCount )
{
//邮票数目小于当前的
if( nCurStampCount < gResultHelper.nCurStampCount )
{
gResultHelper.nCurTypeCount = nCurTypeCount;
gResultHelper.nCurStampCount = nCurStampCount;
gResultHelper.nCurMaxValue = nCurMaxValue;

//更新结果
gResultHelper.bTieFlag = false;//重置tie标记
for( int i = 0; i < nCurStampCount; ++i ) gResultHelper.mResultSets[i]=mIntArray[i];
}
//邮票数目等于当前的
else if ( nCurStampCount == gResultHelper.nCurStampCount )
{
//单张面值最大的大于当前的
if ( nCurMaxValue > gResultHelper.nCurMaxValue )
{
gResultHelper.nCurTypeCount = nCurTypeCount;
gResultHelper.nCurStampCount = nCurStampCount;
gResultHelper.nCurMaxValue = nCurMaxValue;

//更新结果
gResultHelper.bTieFlag = false;//重置tie标记
for( int i = 0; i < nCurStampCount; ++i ) gResultHelper.mResultSets[i]=mIntArray[i];
}
//单张面值最大的等于当前的
else if ( nCurMaxValue == gResultHelper.nCurMaxValue )
{
if ( !gResultHelper.bTieFlag )
{
for( int i = 0; i < nCurStampCount; ++i ) gResultHelper.mResultSets[i]=mIntArray[i];
gResultHelper.bTieFlag = true;//已经tie了
}
}
}
}
}


void GetResult_DFS( int mDstArrayTemp[], int& nCurStampCount, int& nCurTypeCount, int nTarget, int iStart )
{
if ( nTarget < 0 ) return;
if ( nTarget == 0 )
{
//找到一组结果
UpdateBestResult( nCurTypeCount, GetMaxValue( mDstArrayTemp, nCurStampCount ),
nCurStampCount, mDstArrayTemp );

}
else
{
for( int i = iStart; i < gTotalTypeCount; ++i )
{
//后面更大的数不可能满足条件或者邮票数已经是4张,不能容纳更多了(剪枝操作)
if( gStampArray[i] > nTarget || nCurStampCount >= 4 ) break;

//种类数递增
if ( i > iStart || nCurStampCount <= 0 )
{
++nCurTypeCount;
}
mDstArrayTemp[nCurStampCount++] = gStampArray[i];

//因为可以重复使用,所以可继续从当前位置递归
GetResult_DFS( mDstArrayTemp, nCurStampCount, nCurTypeCount, nTarget-gStampArray[i], i );

//重置,即回溯操作
if ( i > iStart || nCurStampCount == 1 )
{
--nCurTypeCount;
}
nCurStampCount--;

}
}
}



//回溯法
int main()
{
IntArray customerVec;

while ( true )
{
int nTemp = 0;
int type[MAX_TYPE_N] = {0}; //面值为i的邮票的种数type[i]
gTotalTypeCount = 0;
//while( cin >> nTemp )
while( true )
{
if ( scanf("%d", &nTemp ) == EOF ) exit(0);

if ( 0 == nTemp || gTotalTypeCount == MAX_TYPE_N ) break;
//gStampArray[gTotalTypeCount++] = nTemp;

if( type[nTemp-1] < 5 ) //剪枝,同面额的邮票种类超过5,则按5计算
{
type[nTemp-1]++;
gStampArray[gTotalTypeCount++] = nTemp;
}

}
sort( gStampArray, gStampArray+gTotalTypeCount );


customerVec.clear();
while( cin >> nTemp )
{
if ( 0 == nTemp ) break;
customerVec.push_back( nTemp );
}


for( int i = 0; i < customerVec.size(); ++i )
{
int iCurTypeCount = 0;
int iCurStampCount = 0;
int mDstVecTemp[MAX_STAMP_N];
memset( mDstVecTemp, 0, sizeof(mDstVecTemp) );
gResultHelper.nCurMaxValue = 0;
gResultHelper.nCurStampCount = 0;
gResultHelper.nCurTypeCount = 0;
gResultHelper.bTieFlag = false;
memset( gResultHelper.mResultSets, 0, sizeof(gResultHelper.mResultSets) );

GetResult_DFS( mDstVecTemp, iCurStampCount, iCurTypeCount, customerVec[i], 0 );


if ( gResultHelper.nCurTypeCount <= 0 )
{
cout << customerVec[i] << " ---- none" << endl;
}
else if ( gResultHelper.bTieFlag )
{
cout << customerVec[i] << " (" << gResultHelper.nCurTypeCount << "): tie" << endl;
}
else
{
cout << customerVec[i] << " (" << gResultHelper.nCurTypeCount << "):";
for( int k = 0; k < gResultHelper.nCurStampCount; ++k )
{
cout << " " << gResultHelper.mResultSets[k];
}
cout << endl;
}
}

}

return 0;
}



 

作者:山丘儿 

标签:nCurMaxValue,OJ,int,nCurStampCount,++,nCurTypeCount,STAMPS,gResultHelper,1010
From: https://blog.51cto.com/u_15905375/5919841

相关文章

  • 抓获Backdoor.Gpigeon.voo和Trojan.PSW.OnlineGames.xd等盗号木马
    endurer原创2007-05-08第1版一位朋友,说他的电脑最近运行很慢,让偶帮忙检修。下载pe_xscan扫描log并分析,发现如下可疑项:/---pe_xscan07-04-12byPurpleEndurer2007-5......
  • 某网络硬盘网站被植入传播Trojan.DL.Inject.xz等的代码
    endurer原创2007-04-30第1版该网站的留言板页面:/---<Iframeid="fralyb"name="fralyb2"src="kh_lyb.aspx?user=2**5***"scrolling="auto"frameborder="0"width=100%h......
  • 某健康学校网站被植入传播Trojan-Downloader.Win32.Delf.bho的代码
    endurer原创2007-04-29 第1版植入的代码为:/---<iframesrc=hxxp://www.1**8d*m***m.com/d***m*/kehu0739.htmwidth=0height=0>---/kehu0739.htm的内容所用代码为US-ASCII。......
  • 一位网友的电脑中了Trojan.PSW.OnlineGames.amc
    endurer原创2007-04-24第1版昨天,一位网友的电脑中了Trojan.PSW.OnlineGames.amc,虽然被瑞星查杀了,但他不太放心,让偶通过QQ远程协助帮忙检查。一看,瑞星实时监控居然没有开,不......
  • ZROJ237 小T的gcd - 数论 -
    题目链接:http://zhengruioi.com/problem/237题解:首先第一问很简单,如果n个数的gcd为1,答案就是n否则为-1考虑第二问,发现由于lcm是小于等于乘积的,若相等则必然两两互......
  • poj3420 Quad Tiling--状压dp+矩阵快速幂
    原题链接:​​http://poj.org/problem?id=3420​​题意:一个4*n的格子,一个1*2的填充,求填充方式。分析:n最大是10^9,比较大,用矩阵快速幂优化速度。#define_CRT_SECURE_NO_DEPREC......
  • poj 2663 Tri Tiling--状压dp
    原题链接:​​http://poj.org/problem?id=2663​​题意:一个3*n的表格,用一个1*2的方块填充,在填满的情况下,一共多少种填充方式。#define_CRT_SECURE_NO_DEPRECATE#include<ios......
  • poj2411 Mondriaan's Dream--状压dp
    原题链接:​​http://poj.org/problem?id=2411​​.题意:一个n*m的方格,给定一个1*2的方块,要求用这个方块填充方格,填满,一共多少种填充方法。分析:对于一行的某一列来说,该列有三......
  • poj 3254 Corn Fields--状压dp入门
    原题链接:​​http://poj.org/problem?id=3254​​题意:给出一个n行m列的草地,1表示肥沃,0表示贫瘠,现在要把一些牛放在肥沃的草地上,但是要求所有牛不能相邻,问你有多少种放法。分......
  • poj1192 最优连通子集--树形dp
    原题链接:​​http://poj.org/problem?id=1192​​题意:其实就是一个求无向树的所有子树和的最大值分析:树形dpdp[i][0]表示以i为根,不包括i结点的子树获得最大权dp[i][1]表......