多重背包问题的优化版来做,详见之前的动态规划读书笔记。
dp[i][j]表示前i中数加得到j时第i种数最多剩余几个(不能加和得到i的情况下为-1)递推式为:
dp[i][j]=mi(dp[i-1][j]≥0,即前i-1种数就能达到数字j)
=-1(j<ai 或者 dp[i][j-ai]≤0,即再加上一个第i种数也无法达到j 或者 当前和小于当前数)
=dp[i][j-ai]-1(可以达到的情况)
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int a[10]; int dp[60000+10]; int main() { int kase=0; while (scanf("%d",&a[1])) { kase++; int sum=a[1]; for (int i=2;i<=6;i++) { scanf("%d",&a[i]); sum+=a[i]*i; } if (sum==0) break; bool f=false; if (sum%2==0) { sum=sum/2; for (int i=1;i<=sum;i++) dp[i]=-1; dp[0]=0; for (int i=1;i<=6;i++) for (int j=0;j<=sum;j++) { if (dp[j]>=0) dp[j]=a[i]; else { if (j<i || dp[j-i]<=0) dp[j]=-1; else dp[j]=dp[j-i]-1; } } if (dp[sum]>=0) f=true; } cout<<"Collection #"<<kase<<‘:‘<<endl; if (f) cout<<"Can be divided."<<endl; else cout<<"Can‘t be divided."<<endl; cout<<endl; } }
时间: 2024-10-24 08:53:38