今天学习的是动态规划。
在我看来动态规划最重要的作用就是缩短代码运行的时间。保证代码高效的运行。也有人说它是利用“空间”换“时间”。
我先举一个例子来说明它的作用:
这是0-1背包问题
问题描述
有n个物品,它们有各自的体积和价值,现有给定容量的背包,如何让背包里装入的物品具有最大的价值总和?(每个物体只有一个)
这道题目是可以使用暴力解法去完成的,但是由于需要遍历所有可能的组合,当物品数量n较大时,计算量会非常大,导致程序运行时间过长。因此,在实际应用中,通常会采用更高效的算法来解决01背包问题,如动态规划(Dynamic Programming)。
好的
我们来设置一下
序号 | 1 | 2 | 3 | 4 |
体积 | 2 | 3 | 4 | 5 |
价值 | 3 | 4 | 5 | 6 |
凭借这个数据完成动态规划
代码如下
#include<iostream>
using namespace std;
#include <algorithm>
int main()
{
int w[5] = { 0 , 2 , 3 , 4 , 5 }; //商品的体积2、3、4、5
int v[5] = { 0 , 3 , 4 , 5 , 6 }; //商品的价值3、4、5、6
int bagV = 8; //背包大小
int dp[5][9] = { { 0 } }; //动态规划表
for (int i = 1; i <= 4; i++)
{
for (int j = 1; j <= bagV; j++)
{
if (j < w[i])
dp[i][j] = dp[i - 1][j];
else
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i]);
}
}
//动态规划表的输出
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 9; j++) {
cout << dp[i][j] << ' ';
}
cout << endl;
}
return 0;
}
没有想象的那么复杂
for (int i = 1; i <= 4; i++)
{
for (int j = 1; j <= bagV; j++)
{
if (j < w[i])
dp[i][j] = dp[i - 1][j];
else
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i]);
}
}
这是不好理解的地方。
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i]);
而这一句就是动态规划的精髓所在。 巧妙地运用在之前就得出的结果,避免了大量的运算过程。
这就是结果,10就是最终的答案。从图中可以看见每一个过程中的最佳解。