有
第
求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。 输出最大价值。
第一行两个整数,$N$,$V$,用空格隔开,分别表示物品数量和背包容积。
接下来有
输出一个整数,表示最大价值。
4 5
1 2
2 4
3 4
4 5
8
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int n,m;
int v[1010],w[1010];
int f[1010][1010];
int main()
{
cin >> n >>m;
for (int i = 1; i <= n; i ++ )
cin >> v[i] >> w[i];
for (int i = 1; i <= n; i ++ )
for (int j = 0; j <= m; j ++ ){
f[i][j]=f[i-1][j];
if(j>=v[i]) f[i][j]=max(f[i][j],f[i-1][j-v[i]]+w[i]);
}
cout << f[n][m] << endl;
return 0;
}
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int n,m;
int v[1010],w[1010];
int f[1010];
int main()
{
cin >> n >>m;
for (int i = 1; i <= n; i ++ )
cin >> v[i] >> w[i];
for (int i = 1; i <= n; i ++ )
for (int j = m; j >= v[i]; j -- )
f[j]=max(f[j],f[j-v[i]]+w[i]);
cout << f[m] << endl;
return 0;
}
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int n,m;
int v,w;
int f[1010];
int main()
{
cin >> n >>m;
for (int i = 1; i <= n; i ++ ){
cin >> v >> w;
for (int j = m; j >= v; j -- )
f[j]=max(f[j],f[j-v]+w);
}
cout << f[m] << endl;
return 0;
}
动态规划+背包问题
核心套路
优化一般就是优化状态转移方程
01背包
特点:每个物品仅能使用一次
重要变量&公式解释
f[i][j]:表示所有选法集合中,只从前i个物品中选,并且总体积≤≤j的选法的集合,它的值是这个集合中每一个选法的最大值.
状态转移方程
$f[i][j] = max(f[i-1][j], f[i-1][j-v[i]]+w[i])$ $f[i-1][j]$ :不选第i个物品的集合中的最大值$f[i-1][j-v[i]]+w[i]$ :选第i个物品的集合,但是直接求不容易求所在集合的属性,这里迂回打击一下,先将第i个物品的体积减去,求剩下集合中选法的最大值.问题
集合如何划分
一般原则:不重不漏,不重不一定都要满足(一般求个数时要满足)
如何将现有的集合划分为更小的子集,使得所有子集都可以计算出来.
注意
优化时
若用到上一层的状态时,从大到小枚举, 反之从小到大哦
作者:竹林正在青 链接:https://www.acwing.com/solution/content/4515/ 来源:AcWing
操作优化
我们注意到在处理数据时,我们是一个物品一个物品,一个一个体积的枚举。
因此我们可以不必开两个数组记录体积和价值,而是边输入边处理。