• [洛谷P1507]NASA的食物计划 以及 对背包问题的整理


    P1507 NASA的食物计划

    题面

    每个物品有三个属性,“所含卡路里”:价值(v),“体积”:限制1(m_1),以及“质量”:限制2(m_2),在n件物品中选择一部分,使得所选物品价值(v)之和最大。
    同时要求这些物品的限制1(m_1)之和不超过限制1上限(c_1),限制2(m_2)之和不超过限制2上限(c_2)

    格式

    输入包括n+2行。
    第一行包括两个整数(c_1,c_2(c_1,c_2<400))
    第二行包括一个整数(n(n<50))
    下面n行,每行包括三个整数(m_1,m_2,v(m_1,m_2<400,v<500))

    输出满足条件的最大的(v)之和

    分析

    看题目能大体猜到是一道背包题。但是与背包不一样的是,限制有两个。
    类比普通背包问题中一般设(dp[i])表示限制为(i)时的最优解,那么我们这里可以设(dp[i][j])表示限制分别为(i)(j)时的最优解。
    下面考虑转移方程式。由于选择一个物品会将两个限制都减少,所以可以得到转移式为(dp[i][j]=max(dp[i][j],dp[i-m1[k]][j-m2[k]]+v[k]))其中k表示考虑第k个物品。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    int c1,c2,n;
    int m1,m2,v;
    int f[402][402];
    int main(){
    	cin>>c1>>c2>>n;
    	for(int k=1;k<=n;k++){
    		cin>>m1>>m2>>v;
    		for(int i=c1;i>=m1;i--)
    			for(int j=c2;j>=m2;j--){
    				f[i][j]=max(f[i][j],f[i-m1][j-m2]+v);
    			}
    	}
    	cout<<f[c1][c2];
    }
    

    后记

    到这里,题已经做出来了。通过这两天刷的这些题,大家应该找到了背包问题的通解。在这里总结一下。

    1. 01背包 一个物品只能选一次 (dp[i]=max(dp[i],dp[i-m[k]]+v[k]) i=c...m[k] O(nc))
    2. 完全背包 一个物品可以选无限次 (dp[i]=max(dp[i],dp[i-m[k]]+v[k]) i=m[k]...c O(nc))
    3. 多维背包 有多个限制 (dp[i1]...[in]=max(dp[i1]...[in],dp[i1-m1[k]]...[in-mn[k]]+v[k]) O(nc1...cn))
    4. 多重背包 一个物品只能选有限次 可以把一个物品分解为多个同样属性的物品,然后用01背包求解(O(sum times[i] *c))(再难一点的做法是二进制优化(O(sum log_2times[i] *c)),甚至单调队列(O(nc))
    5. 超大背包 限制特别大,但是每个物品价值较低 (dp[i]=min(dp[i],dp[i-v[k]]+m[k]))其中(dp[i])表示达到价值i时的最小质量
  • 相关阅读:
    Python中常用的模块(sys模块)
    Python中常用的模块(OS模块)
    Python中常用的模块(time模块)
    Python中常用的模块(random模块)
    Python生成器详解
    Python装饰器详解
    python 两个list 求交集,并集,差集
    数据库中的视图索引
    数据库中的外键和主键理解
    mssql学习
  • 原文地址:https://www.cnblogs.com/water-lift/p/10519436.html
Copyright © 2020-2023  润新知