二維費用的揹包問題
阿新 • • 發佈:2019-01-07
題目:toj3596
題意:有N張光碟,每張光碟有一個價錢,現在要從N張光碟中買M張,預算為L,每張光碟有一個快樂值,要求在不超過預算並且恰好買M張,使得快樂值最大。
解答:典型的二維費用揹包問題,另外一種隱含的費用為個數,每個物品的個數費用為1。要求恰好買M張表示要求恰好裝滿,所以初始化不是0,而是-INF。
二維揹包的狀態轉移方程:F[i, v, u] = max{F[i − 1, v, u], F[i − 1, v − Ci, u − Di] + Wi}
如果空間優化,u,v必須均逆序。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int MAXN = 1010; const int INF = 1 << 31; struct Movie { int t,v; }; Movie movie[MAXN]; int dp[MAXN][MAXN]; int n,m,l; int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d%d",&n,&m,&l); for(int i = 1;i <= m;i++) for(int j = 0;j <= l;j++) dp[j][i] = -INF; for(int j = 0;j <= l;j++) dp[j][0] = 0; for(int i = 1;i <= n;i++) scanf("%d%d",&movie[i].t,&movie[i].v); for(int i = 1;i <= n;i++) for(int j = l;j >= movie[i].t;j--) for(int k = m;k >= 1;k--) dp[j][k] = max(dp[j][k],dp[j-movie[i].t][k-1]+movie[i].v); int ans = 0; for(int i = 1;i <= l;i++) if(dp[i][m] > ans) ans = dp[i][m]; printf("%d\n",ans); } return 0; }