首先说明下:咱们oj上的数据就是给力,完败poj在poj上我明明写错了还是能过,显然数据太水,还是咱们oj好。
本题利用深度优先搜索完成
在搜索到每一个数据时分五个方向向下递归神搜分别是0,1,2,3,4 五个方向
同样设置一个temp 一个ans 找到忧解之后与假定最优解进行比较最后确定最优解
在邮票张数大于4或者说在搜素的种类数已经超过总数时return
还有一个小优化就是在读入数据时注意的问题就是一旦读入的数据出现4个相同值以上时就不再读入 因为再度入也没有了意义
本题利用深度优先搜索完成
在搜索到每一个数据时分五个方向向下递归神搜分别是0,1,2,3,4 五个方向
同样设置一个temp 一个ans 找到忧解之后与假定最优解进行比较最后确定最优解
在邮票张数大于4或者说在搜素的种类数已经超过总数时return
还有一个小优化就是在读入数据时注意的问题就是一旦读入的数据出现4个相同值以上时就不再读入 因为再度入也没有了意义
还有就是数据看似是有序的但是实际上并没有说明 还是要自己排序的
其实这个题目有一个更优秀的解法(不如说是更懒的)直接4个for循环就可以了
回来贴出来看看
题目大意
给你一些邮票的面值,然后给你一些顾客给出的价钱,求出邮票的组合来满足每一位顾客,要求是最多四张邮票,每张可以用多次(其实最多也就四次,因为要求最多四张,否则就是none)。
如:邮票面值1 2 3 0;0代表这行结束
顾客的需求:7 4 0
结果:
7 (3): 1 1 2 3
4 (2): 1 3
解释一下:
由于每次有多种组合,那么如何取结果呢?
如果这些组合都能满足用户的的需求,那么
1.选种类最多的
2.如果种类相同,选总数最多的
3.如果总数相同,选邮票值组合最大值最大的那一组
4.如果连最大值也相同,那么就是tie
5。如果没有这样的组合,也就是不能用4张以内的邮票满足顾客,那么就是none
输出格式,第一个是总价值,括号里面的是邮票的种类,后面是相应的值。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int type[550];
int req[550];
int x;
int num,size;
int flag;
struct node
{
int type_num;
int stamp_num;
int max;
int st[550];
};
node temp,ans;
void init()
{
int i;
flag = 0;
temp.max = 0;
temp.stamp_num = 0;
temp.type_num = 0;
for(i=0;i<26;i++)
temp.st[i]=0;
ans.max = 0;
ans.stamp_num = 0;
ans.type_num = 0;
for(i = 0;i<26;i++)
ans.st[i]=0;
}
void cmp()
{
if(temp.type_num>ans.type_num)
{
ans = temp;
flag = 1;
}
else if(temp.type_num == ans.type_num)
{
if(temp.stamp_num<ans.stamp_num)
{
ans = temp;
flag = 1;
}
else if(temp.stamp_num == ans.stamp_num)
{
if (temp.max>ans.max)
{
ans = temp;
flag = 1;
}
else if(temp.max == ans.max)
{
flag++;}
}
}
}
void dfs(int i, int now_num, int now_sum,int req)
{
if(now_num > 4) return;
if(now_sum ==req)
{
temp.stamp_num = now_num;
temp.type_num = 0;
temp.max = 0;
for(int ii = 0;ii<size;ii++)
{
if(temp.st[ii])
{
temp.type_num++;
if(type[ii]>temp.max)
temp.max = type[ii];
}
}
cmp();
return;
}
if(i>=size||now_sum>req) return;
for(int iii=0;iii<=4;iii++)
{
temp.st[i]+=iii;
dfs(i+1,now_num+iii,now_sum+type[i]*iii,req);
temp.st[i]-=iii;
}
}
void output(int req)
{
printf("%d ",req);
if(flag==0)
printf("---- none\n");
else if(flag ==1)
{
printf("(%d):",ans.type_num);
for(int i=0;i<size;i++)
{
if(ans.st[i]>0)
{
for(int j=0;j<ans.st[i];j++)
printf(" %d",type[i]);
}
}
printf("\n");
}
else
printf("(%d): tie\n",ans.type_num);
}
int main()
{
//freopen("1.txt","r",stdin);
while(scanf("%d",&x)!=EOF)
{
type[0]=x;
size = 1;
while(scanf("%d",&x)==1&&x)
{
int count = 0;
for(int i =0;i<size;i++)
{
if(x ==type[i])
count++;
}
if(count>4) continue;
else type[size++]=x;
}
sort(type,type+size);
num = 0;
while(scanf("%d",&x)==1&&x)
{
req[num++]=x;
}
int h=0;
while(h<num)
{
init();
dfs(0,0,0,req[h]);
output(req[h]);
h++;
}
}
}