DP:0-1背包问题

【问题描述】ios

0-1背包问题:有 N 个物品,物品 i 的重量为整数 wi >=0,价值为整数 vi >=0,背包所能承受的最大重量为整数 C。若是限定每种物品只能选择0个或1个,求可装的最大价值。
能够用公式表示为:
 【算法思路】

动态规划法。咱们能够想到这个问题具备最优子结构性质,假设(x1,x2,...,xn)是最优解,那么在去除x1以后,剩下(x2,...,xn)确定是如下问题的最优解:算法

根据这个特征能够设计DP函数并推出递归关系。具体地,m(i,j)是背包容量为j,可选择物品为i,i+1,…,n时0-1背包问题的最优值。由0-1背包问题的最优子结构性质,则:函数

按着DP[N][C]的矩阵一个一个从 下 往 上 填就能够了,最后的结果是 DP(1,C)。要输出选取的样本编号的时候能够从前日后, DP(1,C)== DP(2,C),则x1=0,不然1,依次类推便可。spa

【代码】设计

 1 #include<iostream>
 2 #include<algorithm>
 3 #include <stdio.h>
 4 #define MAXN 10000
 5 using namespace std;
 6 
 7 int W[MAXN];
 8 int V[MAXN];
 9 int DP[MAXN][MAXN]= {0};
10 
11 int knapsack(int C, int N, int W[], int V[], int DP[][MAXN])
12 {
13     int lackL = min(C, W[N]-1);
14     for(int j = 0; j <=lackL; j++) DP[N][j] = 0;
15     for(int j = W[N]; j <=C; j++) DP[N][j] = V[N];
16     for(int i = N - 1; i>=1; i--){
17         lackL = min(C, W[i]-1);
18         for(int j = 0; j <=lackL; j++) DP[i][j] = DP[i+1][j];
19         for(int j = W[i]; j <=C; j++){
20             DP[i][j] = max( DP[i+1][j], DP[i+1][j-W[i]] + V[i] );
21         }
22     }
23     return DP[1][C];
24 }
25 
26 int main()
27 {
28     int C, N;
29     cin >> C >> N;
30     for(int i = 1; i <=N; i++) {
31         cin >> W[i] >> V[i];
32     }
33     cout<<knapsack(C, N, W, V, DP)<<endl;
34 
35     return 0;
36 }

 

 【拓展】code

若是如今的物品重量weight和背包容量C都是正整数,那么当他们是实数时,如何改进算法知足问题呢?blog

待完善(算法设计与分析P73)递归

相关文章
相关标签/搜索