学习笔记——完全背包问题【I】
一、问题描述
有
N
N
N件物品和一个容量为
V
V
V的背包,每种物品都有无限件可用。
第
i
i
i件物品的体积是
v
i
{v}_{i}
vi,价值是
w
i
{w}_{i}
wi。求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
输出最大价值。
输入格式
第一行两个整数, N N N, V V V,用空格隔开,分别表示物品数量和背包容积。
接下来有 N N N行,每行两个整数 v i {v}_{i} vi, w i {w}_{i} wi,用空格隔开,分别表示第 i i i件物品的体积和价值。
输出格式
输出一个整数,表示最大价值。
数据范围
0
<
N
,
V
≤
1000
0<N,V≤1000
0<N,V≤1000
0
<
0<
0<
v
i
{v}_{i}
vi
,
,
,
w
i
{w}_{i}
wi
≤
1000
≤1000
≤1000
输入样例
4 5
1 2
2 4
3 4
4 5
输出样例:
10
二、解决思路
和0/1背包问题的区别
链接: 算法笔记(一)0/1背包
状态转移方程式
f[j]=max(f[j],f[j-k*v[i]]+k*w[i]); //从0/1背包的状态转移方程式,增加第i个物品拿k个的循环。
三、具体代码
#include <iostream>
using namespace std;
const int N = 1010;
int f[N];
int v[N],w[N],s[N];
int main()
{
int n,m;
cin>>n>>m;
for(int i = 1 ; i <= n ;i ++)
{
cin>>v[i]>>w[i]>>s[i];
}
for(int i=1;i<=n;i++)
for(int j=m;j>=1;--j)
{
for(int k= 0;k<=s[i]&&j>=k*v[i];++k)
{
f[j]=max(f[j],f[j-k*v[i]]+k*w[i]);
}
}
cout<<f[m]<<endl;
}