NYOJ_546_Divideing Jewels
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> #include<string> using namespace std; #define INF 0x80000000 int re[15]; bool dp[100006]; int main() { int t=1,i,j,k,ans; while(~scanf("%d",&re[1])) { ans=re[1]; for(i=2;i<11;++i) { scanf("%d",&re[i]); if(re[i]) ans+=re[i]*i; //ans表示总的珠宝值,它的一半代表可以平分的数 } if(ans==0) break; if(ans&1) { printf("#%d:Can't be divided.\n\n",t++); continue; } ans>>=1; dp[0]=1; for(i=1;i<=ans;++i)//初始化,假设这里的每一个数都不可以划分 dp[i]=0; for(i=1;i<11;++i) for(k=ans;k>=i;--k) { if(dp[ans]) break; //这句话不加也行,加了又省了几百ms for(j=1;j<=re[i]&&k>=j*i;++j) //多重背包 { dp[k]=dp[k-j*i]?1:0; //再说一次,条件表达式是最省时间的,dp[k]表示k容量的背包是否能装满 } } if(dp[ans]) printf("#%d:Can be divided.\n\n",t++); else printf("#%d:Can't be divided.\n\n",t++); } return 0; }
DFS版本别人的代码:
#include<stdio.h> #include<string.h> int a[15]; bool dfs(int n,int money){ if(n==0||money==0){ if(money==0) return true; }else{ for(int i=a[n];i>=0;i--) if(money>=n*i&&dfs(n-1,money-n*i)) return true; } return false; } int main() { int i,sum,T=0; while(1){ for(sum=0,i=1;i<=10;i++){ scanf("%d",&a[i]); sum+=i*a[i]; } if(sum==0) break; if(sum&1) printf("#%d:Can't be divided.\n",++T); else{ if(dfs(10,sum>>1)) printf("#%d:Can be divided.\n",++T); else printf("#%d:Can't be divided.\n",++T); } } return 0; }