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;
}

 

posted @ 2013-05-04 19:56  zhang1107  阅读(189)  评论(0编辑  收藏  举报