uestc STAMPS
转自http://blog.csdn.net/u014634338/article/details/40982369
题目大意(转这里)
给你一些邮票的面值,然后给你一些顾客给出的价钱,求出邮票的组合来满足每一位顾客,要求是最多四张邮票,每张可以用多次(其实最多也就四次,因为要求最多四张,否则就是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
输出格式,第一个是总价值,括号里面的是邮票的种类,后面是相应的值。
注意:第二组数据中 1 1 算不同类型的邮票。
1 #include <iostream> 2 #include <stdio.h> 3 #include <queue> 4 #include <algorithm> 5 #include <string.h> 6 using namespace std; 7 int Stamps[1010]; 8 struct node 9 { 10 int Select[5]; //存储选取的邮票的下标 11 int type; //类型个数 12 int num; //个数 13 int Max; //最大值 14 }a,b; 15 bool istie; 16 bool flag; 17 int n,m; 18 int Type(node &a) //邮票类型数量 19 { 20 bool vis[1010]; 21 memset(vis,false, sizeof(vis)); 22 int cnt=0; 23 for (int i=0; i<a.num; i++) 24 { 25 if(!vis[a.Select[i]]) 26 { 27 cnt++; 28 vis[a.Select[i]]=true; 29 } 30 } 31 return cnt; 32 } 33 int Max_num(node &a) //邮票中最大的值 34 { 35 int max=-1000000; 36 for (int i=0; i<a.num; i++) 37 { 38 if(Stamps[a.Select[i]]>max) 39 { 40 max=Stamps[a.Select[i]]; 41 } 42 } 43 return max; 44 } 45 void judege(node &a,node &b) //判断是否符合更新数据的要求 46 { 47 a.type=Type(a); 48 a.Max=Max_num(a); 49 b.type=Type(b); 50 b.Max=Max_num(b); 51 if(a.num==-1||b.type>a.type || (b.type==a.type && b.num<a.num) || (b.type==a.type && a.num==b.num && a.Max<b.Max)) 52 { 53 a=b; 54 istie=false; 55 return; 56 } 57 if((b.type==a.type && a.num==b.num && a.Max==b.Max)) 58 { 59 istie=true; 60 } 61 } 62 void dfs(int cnt,int pos) //cnt 已组合的邮票的值,pos搜索邮票所在的下标 63 { 64 if(cnt==m) 65 { 66 flag=false; 67 judege(a, b); 68 return; 69 } 70 if(b.num>=4|| cnt>m) //限制搜索深度 71 { 72 return; 73 } 74 for (int i=pos; i<n; i++) 75 { 76 b.Select[b.num]=i; 77 b.num++; 78 dfs(cnt+Stamps[i],i); //可用多次,所以从上次结束的位置开始枚举 79 b.num--; 80 } 81 } 82 void Init() //初始化 83 { 84 istie=false; 85 flag=true; 86 a.num=-1; 87 a.Max=0; 88 a.type=0; 89 90 b.Max=0; 91 b.num=0; 92 b.type=0; 93 } 94 int main() 95 { 96 int x; 97 while (scanf("%d",&x)!=EOF) 98 { 99 Stamps[0]=x; 100 n=1; 101 while (scanf("%d",&x) && x) 102 { 103 Stamps[n++]=x; 104 } 105 sort(Stamps, Stamps+n); //排序 106 while (scanf("%d",&m)&& m) 107 { 108 Init(); 109 dfs(0, 0); 110 printf("%d ",m); 111 if(flag) 112 { 113 printf("---- none\n"); 114 } 115 else 116 { 117 printf("(%d):",a.type); 118 if(istie) 119 { 120 printf(" tie\n"); 121 } 122 else 123 { 124 for (int i=0; i<a.num; i++) 125 { 126 printf(" %d",Stamps[a.Select[i]]); 127 } 128 printf("\n"); 129 } 130 } 131 } 132 } 133 return 0; 134 }