题目条件太多,需要一一提取:
程序目的:根据客户需求和邮票面值为客户分配邮票
1.发行各类邮票最多25枚
2.一次卖邮票不超过四张
3.发行尽可能少的重复邮票
4.最佳组合定义:不同种类邮票数目越多越好
1 #include<cstdio> 2 int stamp[120]; 3 int num; 4 int curs; 5 int curn; 6 int rmax; 7 int zs,zn; 8 int f; 9 int x,rrmax; 10 int now[4]; 11 int wat[4]; 12 13 bool ok(int x) 14 { 15 int sum=0; 16 for(int i=1; i<=num; i++) 17 if(stamp[i]==x) sum++; 18 if(sum>=4) return 0; 19 else return 1; 20 } 21 22 void dfs(int k,int step,int sum) 23 { 24 if(step>=4) 25 { 26 if(sum!=x) return;//连面值都没达到,当然退出 27 28 if(zs>curs)//现在这种方案的种类多 29 { 30 f=0; 31 curs=zs; 32 curn=zn; 33 rmax=rrmax; 34 wat[0]=now[0],wat[1]=now[1],wat[2]=now[2],wat[3]=now[3]; 35 } 36 else if(zs==curs) 37 { 38 if(zn<curn) 39 { 40 f=0; 41 curn=zn; 42 rmax=rrmax; 43 wat[0]=now[0],wat[1]=now[1],wat[2]=now[2],wat[3]=now[3]; 44 } 45 else if(zn==curn) 46 { 47 if(rrmax>rmax) 48 { 49 f=0; 50 rmax=rrmax; 51 wat[0]=now[0],wat[1]=now[1],wat[2]=now[2],wat[3]=now[3]; 52 } 53 else if(rrmax==rmax) 54 { 55 f++; 56 } 57 } 58 } 59 return ; 60 } 61 62 63 64 for(int i=k; i<=num; i++) 65 { 66 if(i==0) zn--;//张数少一张 67 if(i==k) zs--;//种类少一种 68 int tt=rrmax;//用来恢复现场的 69 now[step]=stamp[i]; 70 if(stamp[i]>rrmax) rrmax=stamp[i]; 71 72 dfs(i,step+1,sum+stamp[i]); 73 74 rrmax=tt; 75 if(i==0) zn++; 76 if(i==k) zs++; 77 } 78 } 79 80 int main() 81 { 82 while(scanf("%d",&x)!=EOF) 83 { 84 num=0; 85 stamp[0]=0; 86 stamp[++num]=x; 87 while(scanf("%d",&x)!=EOF) 88 { 89 if(x==0) break; 90 if(ok(x)) stamp[++num]=x; 91 } 92 93 while(scanf("%d",&x)!=EOF) 94 { 95 if(x==0) break; 96 curs=0; 97 curn=0; 98 rmax=-1; 99 rrmax=-1; 100 f=-1; 101 102 zs=4; 103 zn=4; 104 now[0]=now[1]=now[2]=now[3]=0; 105 wat[0]=wat[1]=wat[2]=wat[3]=0; 106 dfs(0,0,0); 107 108 if(f==-1) printf("%d ---- none\n",x); 109 else if(f>=1) printf("%d (%d): tie\n",x,curs); 110 else 111 { 112 printf("%d (%d):",x,curs); 113 114 for(int i=0; i<4; i++) 115 if(wat[i]!=0) printf(" %d",wat[i]); 116 printf("\n"); 117 } 118 } 119 } 120 return 0; 121 }