1、代码
//编译环境vs 2019, 动态规划,0/1背包问题 P139 KNAPSACK算法
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int max(int x, int y);
int main()
{
int n,C;
scanf("%d", &n); //物品个数
scanf("%d", &C); //背包容量
int s[80] = {
0 }, v[80] = {
0}; //s表示体积,v表示价值
for (int i=1;i<=n;i++)
scanf("%d",&s[i]); //需要&符号
for (int i = 1; i <= n; i++)
scanf("%d", &v[i]);
int V[80][80] = {
0 };
for(int i = 0; i <= n; i++)
{
for (int j = 0; j <= C; j++)
{
if (i == 0 || j == 0) //如果当前物品个数为0,或者当前背包容量为0
{
V[i][j] = 0;
continue;
}
if (j < s[i]) //如果这个物品要比此时背包容量还大
V[i][j] = V[i-1][j];
else //如果这个物品能在当前背包中放下
V[i][j] = max(V[i-1][j],V[i-1][j-s[i]]+v[i]);
}
}
for (int i = 0; i <= n; i++)
{
for (int j = 0; j <= C; j++)
{
printf("%d\t",V[i][j]);
}
printf("\n");
}
printf("V[%d][%d]=%d\n",n,C,V[n][C]);
return 0;
}
int max(int x, int y)
{
return x > y ? x : y;
}
2、算法复杂度
时间复杂度看填表的动作,
由于计算当前行时,只需上一次的行,因此对算法稍作修改可以使只需要
3、总结
1、解决动态规划问题的关键是写出递推式。0/1背包问题的基本思想:如果当前物品i放不进当前容量 j ,则V[ i ][ j ]=V[i-1][ j ];如果能放进当前容量 j,那么要考虑是放V[i-1][j-s[ i ] ]+v[ i ]还是不放V[i-1][ j ],哪一个价值大。
详请参见沙特版【算法设计技巧与分析】P138-140
推荐视频:01背包