每一个物品有三个属性,“所含卡路里”:价值\(v\),“体积”:限制1\(m_1\),以及“质量”:限制2\(m_2\),在n件物品中选择一部分,使得所选物品价值\(v\)之和最大。
同时要求这些物品的限制1\(m_1\)之和不超过限制1上限\(c_1\),限制2\(m_2\)之和不超过限制2上限\(c_2\)。c++
输入包括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\)之和spa
看题目能大致猜到是一道背包题。可是与背包不同的是,限制有两个。
类比普通背包问题中通常设\(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个物品。code
#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]; }
到这里,题已经作出来了。经过这两天刷的这些题,你们应该找到了背包问题的通解。在这里总结一下。队列