首先题目描述很让人费解,看了好久才懂。。。
这篇文章对题目的意思描述很清楚http://blog.youkuaiyun.com/huxin2007/article/details/6766074
之后就是代码了,基本思想是dfs+剪枝。但自己在输出全都正确的情况下是wrong answer,,,找了一天,原来是一个bool变量没有置(在代码中已经注释出来了)。
#include<iostream>
#include<algorithm>
using namespace std;
bool tie;//是否输出tie
bool none;//是否输出none
int knum;//总的种类数
int stamps[100];//可用的邮票
int result[4];//存放结果
int lresult[4];//最后结果
bool newresult;//是否为更好的结果
int maxkinds;//目前的最大邮票种类
int minnum;//目前的最小邮票数目
int maxvalue;//存储单个最大的邮票值
void forcustomer(int curnum,int goal,int stampnum,int kinds,int index){
if(goal < 0 || curnum > knum || stampnum >4)
return ;
if(curnum == knum && goal != 0)
return ;
if(goal == 0){
if(kinds > maxkinds){
newresult = true;
}
else if(kinds == maxkinds){
if(stampnum < minnum){
newresult = true;
}
else if(stampnum == minnum){
if(stamps[index] > maxvalue){
newresult = true;
}
else if(stamps[index] == maxvalue){
tie = true;
return;
}
}
}
if(newresult){
//就是这里出错,如果有新的最优值,tie如果为true是没意义的
tie = false;
for(int i= 0;i<stampnum;i++)
lresult[i] = result[i];
maxkinds = kinds;
minnum = stampnum;
maxvalue = stamps[index];
newresult = false;
}
return;
}
for(int i= 0;i< 5;i++ ){
if(i == 0)
forcustomer(curnum+1,goal,stampnum,kinds,index);
else{
if( (i+stampnum)>4)
return;
for(int j = stampnum;j<(i+stampnum);++j)
result[j] = stamps[curnum];
forcustomer(curnum+1,goal-i*stamps[curnum],stampnum+i,kinds+1,curnum);
}
}
return;
}
int main()
{
int goal;
knum = 0;
newresult = false;
while(cin>>stamps[0]){
if(stamps[0] != 0)
{ knum++;
while(cin>>stamps[knum]){
if(stamps[knum] ==0)
break;
++knum;
}
sort(stamps,stamps+knum);
while(cin>>goal){
if(goal == 0)
break;
tie = false;
minnum=999;
maxkinds= 0,maxvalue = -1;
forcustomer(0,goal,0,0,-1);
if(tie){
cout<<goal<<" ("<<maxkinds<<"): "<<"tie"<<endl;
}
else if(minnum == 999){
cout<<goal<<" ---- "<<"none"<<endl;
}
else{
cout<<goal<<" ("<<maxkinds<<"):";
for(int j =0;j<minnum;j++)
cout<<" "<<lresult[j];
cout<<endl;
}
}
}
knum = 0;
}
return 0;
}
当然前面给的那个链接代码更简洁,剪枝也更漂亮。但仅用来参考,最好坚持自己写。