0/1背包问题
假设有n件物品,他们的体积分别为v[i],价值分别为w[i],有一个容量为m的背包,如何选择物品装入背包能够的得到最大的价值。(物品种类不超过N个)
- 条件:每件物品至多只能选择1次
- 状态定义:f [ i ],表示背包体积为 i 时的最大价值
- 转移方程:f [ i ] = max( f [i] , f [ i - v [ i ] ] + w [ i ] )
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
//N的值根据题意设定
const int N = 1000;
int f[N], v[N], w[N], n ,m;
cin >> n >> m;
//循环输入物品的体积和价值
for(int i=0; i<=n; i ++)
cin >> v[i] >> w[i] ;
//对于每件物品
for(int i=1; i<=n; i++)
//因为要使用上一次计算的某个体积时的最大价值,所以从大到小遍历,对于任何可能存在的体积情况,最大价值可能为
//1.上一次计算该体积时的最大价值
//2.上一次计算该体积 - v[i](刚好可以容纳当前物品体积)时的最大价值加上当前物品的价值
for(int j=m; j>=v[i]; j--)
f[j] = max( f[j] , f[j - v[i]] + w[i] );
//不用循环遍历最后一步得到的f数组
//1.因为第二层寻循环每次都从f[m]开始,所以f[m]必存在
//2.如果物品体积全部大于m,则f[m]=0
//3.每次循环对于f[m]来说,都会找到可以加入物品i的合适体积,也就是说这个体积首先可以装入物品i,其次还有
//最大的剩余体积,这些最大的剩余体积的最大价值计算在循环的其他部分完成,并根据计算结果更新最大价值
cout << f[m];
return 0;
}
完全背包问题
假设有n件物品,他们的体积分别为v[i],价值分别为w[i],有一个容量为m的背包,如何选择物品装入背包能够的得到最大的价值。(物品种类不超过N个)
- 条件:每件物品至多能选择无数次
- 状态定义:f [ i ],表示背包体积为 i 时的最大价值
- 转移方程:f [ i ] = max( f [i] , f [ i - v [ i ] ] + w [ i ] )
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
//N的值根据题意设定
const int N = 1000;
int f[N], v[N], w[N], n ,m;
cin >> n >> m;
for(int i=0; i<=n; i ++)
cin >> v[i] >> w[i] ;
for(int i=1; i<=n; i++)
//一个物品可以使用无数次,所以可以使用本次循环计算得到的小体积时的最大价值,从小到大遍历,对于任何可能存在的体积情况,最大价值可能为
//1.上一次计算该体积时的最大价值
//2.上一次计算该体积 - v[i](刚好可以容纳当前物品体积)时的最大价值加上当前物品的价值
for(int j=v[i]; j<=m; j++)
f[j] = max( f[j] , f[j - v[i]] + w[i] );
cout << f[m];
return 0;
}