背包问题可以说是最典型的动态规划问题,从mooc上看了北航的算法课这一部分的讲解,感觉印象有进一步的加深,他把这一种方法叫做备忘录型。
其实本质上我感觉就是利用计算机实现了一个数学表格的一步步推算。
最大的思想就是装还是不装。还有就是动态规划较蛮力枚举的好处不仅仅体现在算法时间复杂度上的提升,还有就是方便了决策重现,输出每一种较为具体的情况。
源码如下附上:
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int main()
{
int w[10] = {-1,15,17,20,12,9,14}; //重量列表
int v[10] = {-1,32,37,46,26,21,30}; //价格列表
int f[10][100];
int n,c;
cout<<"请分别输入物品的总个数和背包的最大容量大小:";
cin>>n>>c;
//初始化备忘录
for(int i=0;i<=c;i++)
{
int res=i-w[1];
if(res<0)
{
f[1][i]=0;
}
else
{
f[1][i]=v[1];
}
}
//往出推整个表
for(int i=2;i<=n;i++)
{
for(int j=0;j<=c;j++)
{
int res=j-w[i]; //能否装入
int temp1=f[i-1][j]; //不装入的价值
int temp2=f[i-1][j-w[i]]+v[i]; //装入的价值
if(res<0)
{
f[i][j]=temp1;
}
else
{
if(temp1>=temp2)
{
f[i][j]=temp1;
}
else
{
f[i][j]=temp2;
}
}
}
}
int MaxValue=f[n][c];
cout<<"背包能装的最大价值为:"<<MaxValue<<endl;
//决策重现
int value=MaxValue;
int weight=c;
int count=n;
cout<<"w"<<" "<<"p"<<endl;
while(count)
{
if(f[count-1][weight-w[count]]+v[count]==value)
{
cout<<w[count]<<" "<<v[count]<<endl;
weight-=w[count];
value-=v[count];
}
count--;
}
}
运行结果:
最强剑道,仍在路上。