【题解】完全背包问题
题目描述
设有n种物品,每种物品有一个重量及一个价值。但每种物品的数量是无限的,同时有一个背包,最大载重量为m,今从n种物品中选取若干件(同一种物品可以多次选取),使其重量的和小于等于m,而价值的和为最大。
输入输出格式
输入格式:
第一行,两个整数,m(背包容量,m≤200)和n(物品数量,n≤30);
第二至第n+1行,每行两个整数wi,ci,表示每个物品的重量和价值。
输出格式:
仅一行,一个数,表示最大总价值。
输入输出样例
输入样例:
10 4
2 1
3 3
4 5
7 9
输出样例:
max=12
这道题是标准的完全背包模板
因为有装或不装两种选择,所以推出动态转移方程
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
注意!
因为每个物品可以装无限个,装完之后还能再装,以前装过的物品也可以对动态转移方程造成影响,与01背包不同,所以DP顺序是从前往后推。
代码:
#include<iostream>
using namespace std;
int m,n,w[35],v[35];
int dp[205];
int main()
{
cin>>m>>n;
for(register int i=1;i<=n;++i) cin>>w[i]>>v[i];
for(register int i=1;i<=n;++i)
{
for(register int j=w[i];j<=m;++j)//为了防止数组越界所以从w[i]开始
{
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
}
}
cout<<"max="<<dp[m];
}