题意:给你n个宝珠,然后给宝珠个价值,价值范围【1,10】,能不能均分给两个人。
输入的数据:价值分别为1,2,3...10的有多少个。
这道题和队友做了好久最终在结束前5分钟AC。。第一次简单的动规结果TLE
不过和队友认为一定是动规。就在想如何优化,想到如果某个价值的个数有偶数个就不判断,奇数个就存入数组。
结果还是wr...我们不放弃啊、、、为就想着写几组数组,当0 2 0 1 0 0 0 0 0 0 输出结果为不能,显然答案是能的。
还剩下不到20分钟了。这个时候就是靠感觉了,直接就写如果某个价值的个数为偶数个只存两个,为奇数个存一个 。
结果AC 那种AC的开心 让人愉悦
代码:
#include <stdio.h> #include <string.h> int a[25],dp[10005],q,maxsum; int main() { int sum,x,step=1,max; while(1) { memset(dp,0,sizeof(dp)); memset(a,0,sizeof(a)); sum=q=maxsum=max=0; for(int i=0;i<10;i++) { scanf("%d",&x); if(x==0)//如果为0,sum++ { sum++; continue; } if(x%2)//如果x为奇数,maxsum记录所有x的和 a[q++]=i+1,maxsum+=i+1; else//如果x为偶数 { a[q++]=i+1; a[q++]=i+1; maxsum=maxsum+2*(i+1); } } if(sum==10)//如果有10个0 break; if(maxsum%2)//如果maxsum不能被2整除 肯定不能均分 { printf("#%d:Can't be divided.\n",step++); printf("\n"); continue; } for(int i=0;i<q;i++)//动规 for(int j=maxsum/2;j>=a[i];j--) { dp[j]=dp[j]; if(dp[j]<dp[j-a[i]]+a[i]) dp[j]=dp[j-a[i]]+a[i]; if(max<dp[j]) max=dp[j]; } if(max==maxsum/2)//如果max等于maxsum的一半 能均分 printf("#%d:Can be divided.\n",step++); else printf("#%d:Can't be divided.\n",step++); printf("\n"); } return 0; }
//搜索方法,同样的原理 #include <stdio.h> #include <string.h> int a[25],flag,visit[25],q,maxsum; void dfs(int star,int sum) { if(sum == maxsum/2) { flag=1; return ; } if(sum>maxsum/2) return ; for(int pre=0,i=star;i<q;i++)//pre优化,如果两个值相等 { if(!visit[i]&&a[i]!=pre) { pre=a[i]; visit[i]=1; sum+=a[i]; dfs(star+1,sum); if(flag) break; sum-=a[i]; visit[i]=0; } } if(flag) return ; } int main() { int sum,x,step=1; while(1) { memset(visit,0,sizeof(visit)); memset(a,0,sizeof(a)); sum=q=maxsum=flag=0; for(int i=0;i<10;i++) { scanf("%d",&x); if(x==0) { sum++; continue; } if(x%2) a[q++]=i+1,maxsum+=i+1; else { a[q++]=i+1; a[q++]=i+1; maxsum=maxsum+2*(i+1); } } if(sum==10) break; if(maxsum%2) { printf("#%d:Can't be divided.\n",step++); printf("\n"); continue; } dfs(0,0); if(flag) printf("#%d:Can be divided.\n",step++); else printf("#%d:Can't be divided.\n",step++); printf("\n"); } return 0; }
时间: 2024-11-09 00:57:57