Fork me on GitHub

DP大作战—组合背包

题目描述

组合背包:有的物品只可以取一次(01背包),有的物品可以取无限次(完全背包),有的物品可以取的次数有一个上限(多重背包)。

DD大牛的伪代码
for i = 1 to N
    if 第i件物品属于01背包
        ZeroOnePack(F,Ci,Wi)
    else if 第i件物品属于完全背包
        CompletePack(F,Ci,Wi)
    else if 第i件物品属于多重背包
        MultiplePack(F,Ci,Wi,Ni)

输入

第一个数为数据组数n 1<=n<=10

接下来n组测试数据,每组测试数据由2部分组成。

第一行为背包容量V,物品种类数N。1<=V<=30000,1<=N<=200

接下来N行每行三个数为物品价值v,物品重量w,物品件数M。M=233表示物品无限。

1<=v,w<=200, 1<=M<=25

输出

对于每组数据,输出一行,背包能容纳的最大物品价值

输入样例

1
10 3
2 2 233
3 2 1
4 3 3

输出样例

13
题目来源:http://biancheng.love/contest/10/problem/F/index
解题思路:
组合背包:0-1背包、完全背包、多重背包。
因此需要结合上述三种背包问题的解决方法来solve组合背包
0-1背包代码:
1 void Zeronepack(int w,int v)
2 {
3     for(int i=V; i>=w; i--)
4         if(dp[i]<dp[i-w]+v)
5             dp[i]=dp[i-w]+v;
6 }

完全背包代码:

1 void Compack(int w,int v)
2 {
3     for(int i=w; i<=V; i++)
4         if(dp[i]<dp[i-w]+v)
5             dp[i]=dp[i-w]+v;
6 }

多重背包代码:

 1 void Multipack(int w,int v,int num)
 2 {
 3     int k;
 4     if(w*num>=V)
 5     {
 6         Compack(w,v);
 7         return;
 8     }
 9     for(k=1; k<num; k<<1)
10     {
11         Zeronepack(k*w,k*v);
12         num-=k;
13     }
14     Zeronepack(num*w,num*v);
15 }

本题组合背包代码:

 

 1 #include <bits/stdc++.h>
 2 int dp[30005];
 3 int V,N;
 4 
 5 void Compack(int w,int v)
 6 {
 7     for(int i=w; i<=V; i++)
 8         if(dp[i]<dp[i-w]+v)
 9             dp[i]=dp[i-w]+v;
10 }
11 
12 void Zeronepack(int w,int v)
13 {
14     for(int i=V; i>=w; i--)
15         if(dp[i]<dp[i-w]+v)
16             dp[i]=dp[i-w]+v;
17 }
18 
19 void Multipack(int w,int v,int num)
20 {
21     int k;
22     if(w*num>=V)
23     {
24         Compack(w,v);
25         return;
26     }
27     for(k=1; k<num; k<<1)
28     {
29         Zeronepack(k*w,k*v);
30         num-=k;
31     }
32     Zeronepack(num*w,num*v);
33 }
34 
35 int main()
36 {
37     int kase,v,w,m;
38     scanf("%d",&kase);
39     while(kase--)
40     {
41         memset(dp,0,sizeof(dp));
42         scanf("%d%d",&V,&N);
43         for(int i=1;i<=N;i++)
44         {
45             scanf("%d%d%d",&v,&w,&m);
46             if(m==1)
47                 Zeronepack(w,v);
48             else if(m==233)
49                 Compack(w,v);
50             else
51                 Multipack(w,v,m);
52         }
53         printf("%d\n",dp[V]);
54     }
55     return 0;
56 }

 

posted @ 2015-11-24 16:08  伊甸一点  阅读(490)  评论(0编辑  收藏  举报