目录
一、目的
能正确利用动态规划法解决01背包问题,能够写出动态规划函数,分析边界值测试效果,能够正确地分析时间复杂度
二、设计思路
分析问题后,可以得出01背包问题可以看做是决策一个序列,对任意变量x的决策是决定x=1或者是x=0.如果将二维数组V(n,c)表示将n个物品装入容量为c的背包获得的最大价值,则初始子问题就是把前面i个物品装入容量为0的背包和把0个物品装入容量为j的背包。
Int V[] // 存储最大价值
Int x[] // 存储装入背包的物品
Int w[] //存储物品的重量
Int v[] //存储物品的价值
Int n //物品的数量
Int c //背包的容量
三、流程图
四、动态规划函数
当决策x时,问题处于两种状态,一种是背包不足以装入物品,则装入的物品当前价值与之前的物品价值一样,背包不增加价值,一种是背包可以装入物品,如果把当前物品装入背包那么当前价值就是减去这个物品的容量后的最大价值加上这个物品的价值,然后比较二者取较大值,动态规划函数如下:
五、时间复杂度分析
N是物品的数量,C是背包的容量,该算法里面有两个嵌套的for循环,其时间复杂度为O(N*C)还有一个时间复杂度为O(N)的for循环,所以算法的时间复杂度为O(N*C)
六、实验步骤和调试过程
1.测试数据设计
N和C的规模 | 5000 | 10000 | 15000 | 20000 | 25000 | 30000 | 35000 | 40000 |
耗时(ms) | 192 | 772 | 1705 | 3062 | 5089 | 7746 | 12091 | 17800 |
2.测试结果散点图
七、代码
#include<iostream>
#include<stdio.h>
#include<time.h>
using namespace std;
int** V;
int* x;
int bag(int w[], int v[], int n, int c)
{
int i, j;
for (i = 0; i <= n; i++)
for (j = 0; j <= c; j++)
{
V[i][j] = 0;
}
for (i = 1; i <=n; i++)
{
for (j = 1; j <=c; j++)
{
if (j < w[i-1])V[i][j] = V[i - 1][j];//不能被装入背包
else V[i][j] = max(V[i - 1][j], V[i - 1][j-w[i-1]] + v[i-1]);//能被装入背包
}
}
for (i = n,j=c; i > 0; i--)
{
if (V[i][j] > V[i - 1][j])
{
x[i - 1] = 1;
j = j - w[i - 1];
}
else
x[i - 1] = 0;
}
return V[n][c];
}