3 1 2 4 3 9 2 1
0 2 4 5这个题 丫的浪费好长时间 好几个小时 ,唉 都怪自己笨 ,用母函数来做,母函数部分算出所有可能组合出来的值得情况。假设先把最大值的组合情况放在左盘,从1开始检测所有组合情况,这个最大值的来源有两种情况,case1:前面某些较小的砝码组合,case2:本身那个砝码就最大。对于case1:那个最大值组合减去其他某种组合情况之一相当于 左盘减 右盘加!!对于 case2:相当于左盘不变,从砝码箱里取出其他砝码组合加入到右盘。最坑人的是 超时好几次!稍微优化了一下,比规定时间少2毫秒!哈哈哈#include<iostream> #include<stdio.h> #include<string.h> using namespace std; int cnt[100002],dic[100002]; int main() { int n,A[101]; while(scanf("%d",&n)!=EOF) { int Max=0; for(int i=0; i<n; i++) { scanf("%d",&A[i]); Max+=A[i]; } for(int j=0; j<=Max; j++) { cnt[j]=0; dic[j]=0; } cnt[0]=cnt[A[0]]=1; for(int t=2; t<=n; t++) { for(int k=0; k<=Max; k++) { if(cnt[k])//如果前一对括号中某个指数的系数为0,那么即使乘以下一项,也不会给当前括号内某一项指数和为T的系数有效力 { for(int h=0; h+k<=Max&&h<=A[t-1]; h+=A[t-1]) { dic[k+h]+=cnt[k]; } } } for(int p=0; p<=Max; p++) { cnt[p]=dic[p]; dic[p]=0; } } int buff[Max+1]; memset(buff,0,sizeof(buff)); for(int q=Max; q>=1; q--) { if(cnt[q]) { for(int f=1; f<=q; f++) { if(cnt[f]) { if(f==q) buff[q]=1; else buff[q-f]=1; } } } } int ls[Max+1],r,count=0,t=0,flag=0; memset(ls,0,sizeof(ls)); for(int a=1; a<=Max; a++) { if(!buff[a]) { ls[t++]=a,count++; flag=1; } } if(!flag) { cout<<0<<endl; continue; } cout<<count<<endl; for( r=0; r<t-1; r++) cout<<ls[r]<<" "; cout<<ls[r]<<endl; } return 0; }
原文地址:http://blog.csdn.net/lsgqjh/article/details/45287179