【题解】完全背包问题

题目描述

设有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];
}
posted @ 2019-11-25 13:57  X_OR  阅读(517)  评论(0编辑  收藏  举报