北大OJ_1010题:STAMPS

来源:互联网 发布:返利网如何解绑淘宝号 编辑:程序博客网 时间:2024/05/16 01:46
#include <iostream>#include <vector>#include <algorithm>using namespace std;typedef vector<int> IntArray;#defineMAX_STAMP_N4//最大邮票数#defineMAX_TYPE_N25//最大邮票种类数25struct 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;}



参考文章:http://blog.csdn.net/lyy289065406/article/details/6647948



作者:山丘儿
转载请标明出处,谢谢。原文地址:http://blog.csdn.net/s634772208/article/details/46726249


0 0
原创粉丝点击