【动态规划/多重背包问题】POJ1014-Dividing

多重背包问题的优化版来做,详见之前的动态规划读书笔记。

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(可以达到的情况)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 
 6 int a[10];
 7 int dp[60000+10];
 8 
 9 int main()
10 {
11     int kase=0;
12     while (scanf("%d",&a[1]))
13     {
14         kase++;
15         int sum=a[1];
16         for (int i=2;i<=6;i++)
17         {
18             scanf("%d",&a[i]);
19             sum+=a[i]*i;
20         }
21         if (sum==0) break;
22         
23         
24         bool f=false;
25         if (sum%2==0)
26         {
27             sum=sum/2;
28             for (int i=1;i<=sum;i++) dp[i]=-1;
29             dp[0]=0;
30             for (int i=1;i<=6;i++)
31                 for (int j=0;j<=sum;j++)
32                 {
33                     if (dp[j]>=0) dp[j]=a[i];
34                     else
35                     {
36                         if (j<i || dp[j-i]<=0) dp[j]=-1;
37                             else dp[j]=dp[j-i]-1;
38                     }
39                 }
40             if (dp[sum]>=0) f=true;
41         }     
42         cout<<"Collection #"<<kase<<':'<<endl;
43         if (f) cout<<"Can be divided."<<endl;
44         else cout<<"Can't be divided."<<endl;
45         cout<<endl;
46     }
47 }
原文地址:https://www.cnblogs.com/iiyiyi/p/4605831.html