• 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;
    }
    
  • 相关阅读:
    String与StringBuffer
    oracleSQL文
    中国IT成功人士特点6大成功密码全解析
    对java学习有帮助
    Spring之工厂模式
    搭建IBatis 框架
    单例模式(Singleton)
    UVa 10180 Rope Crisis in Ropeland!
    HDU 3711 Binary Number
    UVaLive 4643 / LA 4643 Twenty Questions(对题意的解释已修改)
  • 原文地址:https://www.cnblogs.com/zxjhaha/p/11320822.html
Copyright © 2020-2023  润新知