dp背包

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 
 5     /*初始化的细节问题 我们看到的求最优解的背包问题题目中,事实上有两种不太相同的问法。
 6 
 7 
 8     有的题目要求“恰好装满背包”时的最优解,有的题目则并没有要求必须把背包装满。一种区别这两种问法的实现方法是在初始化的时候有所不同。
 9 如果是第一种问法,要求恰好装满背包,那么在初始化时除了 f[0]为 0 其它 f[1..V]均设为-∞,这样就可以保证最终得到的 f[N]是一种恰好装满背包
10 的最优解。
11     如果并没有要求必须把背包装满,而是只希望价格尽量大,初始化时应该将 f[0..V]全部设为 0。
12 
13 
14     为什么呢?可以这样理解:初始化的 f 数组事实上就是在没有任何物品可以放入 背包时的合法状态。
15 如果要求背包恰好装满,那么此时只有容量为 0 的背包可能 被价值为 0 的 nothing“恰好装满”,其它容
16 量的背包均没有合法的解,属于未 定义的状态,它们的值就都应该是-∞了。如果背包并非必须被装满,那
17 么任何 容量的背包都有一个合法解“什么都不装”,这个解的价值为 0,所以初始时状 态的值也就全部为 0 了。*/
18 
19 
20 
21 //01背包
22 void ZeroOnePack(cost,weight)
23 {
24     for(int v=V;v>=cost;v--)
25         f[v]=max(f[v],f[v-cost]+weight);
26 }
27 
28     for i=1...N
29         ZeroOnePack(c[i],w[i]);
30 
31 
32 //完全背包
33 void CompletePack(cost,weight)
34 {
35     for(int v=cost;v<=V;v++)
36         f[v]=max(f[v],f[v-cost]+weight);
37 
38 }
39 
40     for i=1...N
41         CompletePack(c[i],w[i]);
42 
43 
44 //多重背包
45 
46 //方法一:每种物品分解为多个  01背包求解
47 void MultiplePack(cost,weight,amount)
48 {
49     for(int v=V;v>=cost;v--)
50         for(int k=0;k<amount;k++)
51             f[v]=max(f[v],f[v-cost]+weight);
52 }
53 
54     for i=1...N
55         MultiplePack(c[i],w[i],n[i]);
56 
57 
58 //方法二:二进制优化
59 void MultiplePack(cost,weigt,amount)
60 {
61     if(cost*amount>=V)//全部装不下  当完全背包 可取任意多个
62         {
63             CompletePack(cost,weight);
64             return ;
65         }
66 
67     int k=1;
68     while(k<amount)
69     {
70         ZeroOnePack(k*cost,k*weight);
71         amount-=k;
72         k<<1;//k*=2;
73     }
74     ZeroOnePack(amount*cost,amount*weight);
75 }
原文地址:https://www.cnblogs.com/reminito/p/8398469.html