题解:P2967 [USACO09DEC] Video Game Troubles G
很好的一道题,使我的背包旋转,
Solution P2967
Idea
如果我们直接背包,第一不方便考虑限制,第二可能会 TLE。
但是不难发现每一个游戏机之间是不冲突的。这意味着第 个游戏机如何选取不会影响第 个游戏机的选取。
我们考虑每个游戏机当做一个子任务。然后对这个子任务跑 01 背包。
设 为考虑到游戏机 的总花费为 的最大价值。
对于选了的情况,显然有先选这个游戏机的价格:,其中 为游戏机价格。
然后选游戏,做 01 背包即可,,其中 为游戏价格, 为价值。、
可能有人会问为什么是 。实际上因为限制,我们要求转移必须以选了这个游戏机作为前提。如果先转移选了,这个时候 一定是一个选了的状态。
如果这个游戏机不选,就很简单:。
Code
#include<bits/stdc++.h>
using namespace std;
const int N=55,M=100005;
int n,m,w,v,d,dp[2][M],k;
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d%d",&d,&k);
for(int j=d;j<=m;j++){
dp[i&1][j]=dp[(i-1)&1][j-d];
}
while(k--){
scanf("%d%d",&v,&w);
for(int j=m;j>=v+d;j--){//v+d 的原因是要包括游戏机的价格
dp[1&i][j]=max(dp[i&1][j],dp[i&1][j-v]+w);
}
}
for(int j=0;j<=m;j++){
dp[i&1][j]=max(dp[i&1][j],dp[(i-1)&1][j]);
}
}
printf("%d",dp[n&1][m]);
return 0;
}

浙公网安备 33010602011771号