动态规划 - 01背包空间优化
1.若只求最大价值,可优化空间复杂度,用一维数组存储动态规划表
(1)这是一个使用二维数组存储的动态规划表
![](https://i-blog.csdnimg.cn/blog_migrate/a86afa082ea27137a7bf95422ab72b6e.jpeg)
(2)求(动态规划表)dpt[i][j]值 ,只需要用到动态规划表第i-1行的第j列之前的数据
要求3行6列的绿色方框4 只需要用表中到第2行 前5个数字(红色小方框内的数字)
(3)想象求第j个值 需要用到前j-1个值,如此需要从后向前遍历(循环)方能不覆盖有用的值。简单说,就是用一维数组存储动态规划表,计算其值的时候从后先前遍历即可。
这样前几个存储的是上一次循环求得的,后面的都是最新的值。
二维数组 and 一位数组 两种存储方式对比代码(具体实现细节)如下:
//VC6.0--------------------------
#include "stdafx.h"
#include <cmath>
#include <iostream>
using namespace std;
//----------全局变量(输入信息)------------
#define n 4 //数量
#define max_w 8 //最大重量
int v[n]={2,3,4,5}; //价值
int w[n]={3,4,5,6}; //重量
//----------最大值函数--------
int max(int a,int b){
if(a>b) return a;
else return b;
}
//-----------------------01背包-二维动态规划表-----------------------
void beibao01_2()
{
int i,j;
int dpt[n][max_w+1]={0}; //动态规划表
//--------------第一行------------
for (j = 0; j <= max_w; j++)
if(j >= w[0])
dpt[0][j] = v[0];
//--------------其余行------------
for (i = 1; i < n; i++)
{
for (j = 1; j <= max_w; j++)
{
if (j < w[i])
dpt[i][j] = dpt[i-1][j];
else
{
dpt[i][j] = max(dpt[i-1][j], dpt[i-1][j-w[i]] + v[i]);
}
}
}
//输出
cout<<"二维动态规划表;"<<endl;
for (i = 0; i < n; i++)
{
for (j = 0; j <= max_w; j++)
{
cout<<dpt[i][j]<<" ";
}
cout<<endl;
}
cout<<endl;
}
//-----------------------01背包-一维动态规划表-----------------------
void beibao01_1()
{
int i,j;
int dpt[max_w+1]={0}; //动态规划表
cout<<"一维动态规划表每次循环完后的结果:"<<endl;
for (i = 0; i < n; i++)
{
for (j = max_w; j >=w[i] ; j--)
{
dpt[j] = max(dpt[j],dpt[j-w[i]]+v[i]);
}
cout<<i<<":";
for (int jj = 0; jj <= max_w; jj++)
cout<<dpt[jj]<<" ";
cout<<endl;
}
//输出
cout<<"一维动态规划表;"<<endl;
for (j = 0; j <= max_w; j++)
cout<<dpt[j]<<" ";
cout<<endl;
}
//------------------------------------------------------
void main()
{
beibao01_2();
beibao01_1();
}
![](https://i-blog.csdnimg.cn/blog_migrate/3d51491dd71b4691cd678df25d6c6210.jpeg)
2.用一维数组存储动态规划表,只求最大价值,简化代码如下:
//VC6.0--------------------------
#include "stdafx.h"
#include <cmath>
#include <iostream>
using namespace std;
//----------全局变量(输入信息)------------
#define n 4 //数量
#define max_w 8 //最大重量
int v[n]={2,3,4,5}; //价值
int w[n]={3,4,5,6}; //重量
//----------最大值函数--------
int max(int a,int b){
if(a>b) return a;
else return b;
}
//-----------------------01背包-一维动态规划表-----------------------
void beibao01_1()
{
int i,j;
int dpt[max_w+1]={0};
//注意这里的循环次数 可少循环一次
for (i = 0; i < n-1; i++)
{
for (j = max_w; j >=w[i] ; j--)
{
dpt[j] = max(dpt[j],dpt[j-w[i]]+v[i]);
}
}
//其从后向前遍历的 只求最大值 则最后一次循环只求最后动态规划表(一维数组)的最后一个值即可
dpt[max_w] = max(dpt[max_w],dpt[max_w-w[n-1]]+v[n-1]);
cout<<"最大价值:"<<dpt[max_w]<<endl;
}
//------------------------------------------------------
void main()
{
beibao01_1();
}
![](https://i-blog.csdnimg.cn/blog_migrate/88054a71bec941bbce690c5b8e0d948e.jpeg)