zxjssf

01背包

题目

试题描述

经典的 0-1 背包:知道 n 个物品的体积和价值,第 i 个体积为 V[i],价值为 W[i],有一个背包的容积为 C。求在体积不超容积的前提下,背包中可装物品价值的最大值。

输入
第一行:两个整数 n 和 C ;
第 2 行到第 n+1 行:每行两个整数 Vi 与 Wi,有一个空格分隔。
输出
一个数,表示背包中能得到物品价值的最大值。 
输入示例
2 10
1 1
2 2
输出示例
3
其他说明
数据范围:输入的数据均不超过20,经典的dp。

分析

这是经典的01背包问题,最基础的动态规划。noip考了不下5次。

所谓动态规划就是是通过组合子问题的解来求解原问题的。而类似递推(不会递推看:https://www.cnblogs.com/zxjhaha/p/11295080.html),动态规划有一个转移方程。通过已知转移未知。所以关键在于求出转移方程。让我们来看看这道题。

首先,定义一个dp数组,dp[i][j]表示前i个物品剩余体积为j的最大价值。我们所以要面临的就是取与不去的问题。转移方程如下。

 注:c数组表示物体重量,v数组表示价值。

完整代码如下。

#include <bits/stdc++.h>
using namespace std;
int n,m,dp[10005][10005],c[25],v[25];
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>c[i]>>v[i];
	for(int i=1;i<=n;i++)
	{
		for(int j=0;j<=m;j++) //枚举从0到m 
		{
			if(j>=c[i]) dp[i][j]=max(dp[i-1][j],dp[i-1][j-c[i]]+v[i]); //如果放得下,就带入转移方程。 
			else dp[i][j]=dp[i- 1][j]; //不放的情况 
		}
	}
	cout<<dp[n][m]; //输出前n个物品剩余体积为m的最大价值。 
	return 0;
}

 

posted @ 2019-08-08 14:42  zxjssf  阅读(267)  评论(1编辑  收藏  举报