HDU2159 二重完全背包

和普通的完全背包不同的地方时多了物品选取的限制,因此需要增加一维

dp[i][j][k]表示前i种物品,选取j个放入容量为k的背包中所能得到的最大价值

这里和一维的背包一样可以利用滚动数组省略一维即

dp[i][j] 表示前选取i个放入容量为j的背包所能得到的最大价值

dp[i,j] = max(dp[i,j],dp[i-1][j-w[k]]+v[k]);

 

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <string>
 4 #include <algorithm>
 5 #include <iostream>
 6 using namespace std;
 7 #define INF 0x3fffffff
 8 const int maxn = 105;
 9 const int maxv = 105;
10 int dp[maxv][maxn],w[maxn],v[maxn];
11 int main()
12 {
13    //freopen("in.txt","r",stdin);
14     int n,m,k,s;
15     while(cin>>n>>m>>k>>s)
16     {
17         for(int i = 1;i<=k;++i)
18             scanf("%d%d",v+i,w+i);
19         memset(dp,0,sizeof(dp));
20         int flag = 0,ans = -1;
21         for(int j = 0;j<=m;++j)
22         {
23             for(int i = 1;i<=s;++i)
24             {
25                 for(int x = 1;x<=k;++x)
26                     if(j>=w[x]){
27                             dp[i][j] = max(dp[i][j],dp[i-1][j-w[x]]+v[x]);
28                             if(dp[i][j]>=n){flag = 1;ans = j;break;}
29                     }
30                 if(flag)break;
31             }
32             if(flag)break;
33         }
34         if(flag)printf("%d\n",m-ans);
35         else puts("-1");
36     }
37     return 0;
38 }

 

posted on 2014-09-19 21:47  round_0  阅读(184)  评论(0)    收藏  举报

导航