程序博客网 > 华夏信用卡软件
来源:互联网 发布:华夏信用卡软件 编辑:程序博客网 时间:2024/06/06 09:56
///动态规划,又有点筛选法的思想,按价值划分状态,要求能否划分出一半的价值也就是求//value[halfvalue]的状态。 #include<stdio.h>#include<string.h>//保存每一种价值的石头 int num[7];//value[i]用来指示是否能划分出i的石头出来,1则能划分出来,反之为0。 bool value[100005];int main(){freopen("divide.in","r",stdin);freopen("ans.txt","w",stdout);int cas=0;while(1){int i,j,sum=0;for(i=1;i<=6;i++){scanf("%d",&num[i]);sum+=num[i]*i;}if(!sum)break;cas++;int halfvalue=sum/2;//检查价值之和能否被2整除 if(sum&1)printf("Collection #%d:/nCan't be divided./n/n",cas);else{int t=0,k,end=0,temp;memset(value,0,sizeof(value));value[0]=1;for(i=1;i<=6;i++){if(num[i]>0){//从大到小查找比由小到大更快找到结果,另外也可以避免出现将状态由0变为1后对当前循环的影响//例如0 0 0 2 2 1就会出现这样的情况 for(j=t;j>=0;j--){if(value[j]){for(k=1;k<=num[i];k++){//如果当前j+k*i大于halfvalue,那么对于k+1,k+2..均大于halfvalue if(j+k*i>halfvalue) break; if(!value[j+k*i]){value[j+k*i]=1;}//如果value[j+k*i]=1,因j从大到小,所以j+(k+1)*i等等会大于halfvalue或已经为1。 elsebreak;//如果已经划分出halfvalue,则没必要继续,应该退出 if(j+k*i==halfvalue){end=1;break;}}}if(end)break;}}if(end)break;t+=num[i]*i;if(t>halfvalue)t=halfvalue;}if(value[halfvalue]) printf("Collection #%d:/nCan be divided./n/n",cas); else printf("Collection #%d:/nCan't be divided./n/n",cas);}}return 0;}