The Right Tip [UVA 1163]
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34348
View Code
const int MM = 11111; #define debug puts("wrong") //typedef __int64 int64; int p[MM]={1,2,5,10,20,50,100,200}; int num[MM], g[MM], gg[MM]; int N,M,sum=0; void get_data() { int i,j,k; for(i=sum=0;i<8;i++) { scanf("%d",&num[i]); sum+=p[i]*num[i]; } } //暴力枚举不明白为什么要把5合并到10,50合并到100 bool ok() { int i,j,k,tt; for(i=0;i<8;i++) if(g[i]<0) return false; for(i=0;i<N;i++) if(gg[i]<0) return false; // if(g[2]%2==1 || g[5]%2==1) return false; // g[3]+=g[2]/2; g[2]=0; g[6]+=g[5]/2; g[5]=0; for(i=0;i<N;i++) { for(j=7;j>=0;j--) { if(gg[i]>=(p[j]*g[j])) { gg[i]-=(p[j]*g[j]); g[j]=0; } else { tt=gg[i]/p[j]; g[j]-=tt; gg[i]-=(tt*p[j]); } } if(gg[i]!=0) return false; } return true; } void solve() { int i,j,k,tmp,x,y,l; if(sum%N) {puts("no");return;} else { tmp=sum/N; bool ff=false; for(i=0;i<(1<<N);i++) { for(j=0;j<(1<<N);j++) { for(k=0;k<(1<<N);k++) { for(x=0;x<(1<<N);x++) { for(l=0;l<8;l++) g[l]=num[l]; for(l=0;l<N;l++) gg[l]=tmp; for(l=0;l<N;l++) if(i&(1<<l)) {g[7]--;gg[l]-=200;} for(l=0;l<N;l++) if(j&(1<<l)) {g[2]--;gg[l]-=5;} for(l=0;l<N;l++) if(k&(1<<l)) {g[4]--;gg[l]-=20;} for(l=0;l<N;l++) if(x&(1<<l)) {g[5]--;gg[l]-=50;} if(ok()) { ff=true;goto loop; } } } } } loop: puts(ff?"yes":"no"); } } int main() { while(scanf("%d",&N),N!=-1) get_data(),solve(); return 0; }