1.0-1背包的朴素形式
0-1背包问题:给定编号为1,2...n的n个物品和一个容量为C的背包;每个物品的重量为$w_i$,每个物品的价值为$v_i$,求将物品装入背包后,背包能获得的最大价值。其状态转移方程为:
$$ dp[i][j] = egin{cases} max{dp[i-1][j],dp[i-1][j-w_i] + v_i} ,& {j ≥ w_i} \ dp[i-1][j] , & {j < w_i} end{cases} $$
其中dp[i][j]表示把编号为从1到i的i个物品放入容量为j的背包所得到的最大的价值。其实现代码如下:
#include<iostream>
#include<unordered_map>
#include<queue>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<sstream>
#include<set>
#include<map>
#include<stack>
#define MAX_NUM 100
using namespace std;
/*0-1背包的朴素形式*/
int main()
{
int n,C;//n为物品的个数,C为背包的容量
int weight[MAX_NUM];
int val[MAX_NUM];
int dp[MAX_NUM][MAX_NUM];
cout<<"输入物品个数和背包容量:"<<endl;
cin>>n>>C;
cout<<"分别输入这"<<n<<"个物品的重量和价值:"<<endl;
for(int i = 1; i <= n; i++)
cin>>weight[i]>>val[i];
memset(dp,0,sizeof(dp));//初始化dp数组
for(int i = 1; i <= n; i++)
for(int j = 1; j <= C; j++) //此处j的初值也可以为weight[i]开始,其实这样效率更高;不过为了便于理解才写成从1开始
{
if(j < weight[i])
dp[i][j] = dp[i- 1][j];
else
dp[i][j] = max(dp[i - 1][j],dp[i-1][j - weight[i]] + val[i]);
}
cout<<"背包的最大价值为:"<<dp[n][C]<<endl;
}
这种朴素形式的0-1背包的算法的时间复杂度为O(n*C),空间复杂度也为O(n*C)。
2.对0-1背包进行优化
对0-1背包的优化主要体现在空间复杂度的优化上,时间复杂度无法再优化了。可以参考:https://blog.csdn.net/hearthougan/article/details/53869671 或者 https://blog.csdn.net/yoer77/article/details/70943462
或者 https://www.cnblogs.com/fengziwei/p/7750849.html 。

其实现代码如下:
#include<iostream>
#include<unordered_map>
#include<queue>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<sstream>
#include<set>
#include<map>
#include<stack>
#define MAX_NUM 100
using namespace std;
/*0-1背包的优化形式*/
int main()
{
int n,C;//n为物品的个数,C为背包的容量
int weight[MAX_NUM];
int val[MAX_NUM];
int dp[MAX_NUM];//变成了一位数组
cout<<"输入物品个数和背包容量:"<<endl;
cin>>n>>C;
cout<<"分别输入这"<<n<<"个物品的重量和价值:"<<endl;
for(int i = 1; i <= n; i++)
cin>>weight[i]>>val[i];
memset(dp,0,sizeof(dp));//初始化dp数组
for(int i = 1; i <= n; i++)
for(int j = C; j >= 1; j--) //此处j的初值变成了C,然后递减;与朴素形式调过来了;当然此处的中止条件也可为j >= weight[i]
{
if(j < weight[i])
dp[j] = dp[j];
else
dp[j] = max(dp[j],dp[j - weight[i]] + val[i]);
}
cout<<"背包的最大价值为:"<<dp[C]<<endl;
}
优化后的0-1背包算法,时间复杂度仍为O(n*C),空间复杂度变成了O(C)。