#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;
}



 

作者:山丘儿