动态规划-01背包问题
描述:
有n中物品,第i个物品的质量为wi,体积为vi,背包的体积容量为c;使得背包内物品在总体积不超过c的前提下重量最大
思路:
典型的动态规划思想,在遇到第i个物品的时候,我们有两种情况,
1、装入背包(装的下的前提下),那么f[i][j] = f[i-1][j]
2、不装入背包,那么f[i][j] = f[i-1][j-v[i]] + w[i]
所以状态转移方程为:
f[i][j] = max( f[i-1][j] , f[i-1][j-v[i]] + w[i])
代码:
#include<iostream>
using namespace std;
int main()
{
int n,c;//数量,背包容量
int w,v;//重量,体积
cin>>n>>c;
int f[100][100] = {0};
for (int i=1;i<=n;i++)
{
cin>>v>>w;
for(int j=1;j<=c;j++)
{
if(j >= v)
{
f[i][j] = max(f[i-1][j],f[i-1][j-v] + w); //状态转移方程
}
}
}
printf("********\n动态结果如下\n");
for(int i=1;i<=n;i++)
{
for(int j=1;j<=c;j++)
{
printf("%3d ",f[i][j]);
}
printf("\n");
}
return 0;
}
一维数组的思路
当然我们也可以用一维数组来做,那么此时的状态方程变成了:
f[j] = max(f[j] , f[j-v]+w)
(此时f[j]存放的是f[i-1][j],f[j-v]存放的是f[i-1][j-v],类似于a = a +2的赋值操作,左边的a和右边的a有时序差别,所以就是比较i-1时刻的f值,赋给i时刻的f)
代码:
#include<iostream>
using namespace std;
int main()
{
int n,c;//数量,背包容量
int w,v;//重量,体积
cin>>n>>c;
int f[100]={0};
for (int i=1;i<=n;i++)
{
cin>>v>>w;
for (int j = c;j>=1;j--)
{
if(j>=v)
f[j] = max(f[j],f[j-v]+w);
}
//在这里输出动态的存放过程
for(int j=1;j<=c;j++)
printf("%3d ",f[j]);
printf("\n");
}
return 0;
}