P2967 [USACO09DEC]视频游戏的麻烦Video Game Troubles
冲刺阶段的首篇题解!
题目链接:P2967 [USACO09DEC]视频游戏的麻烦Video Game Troubles;
题目概述:
总共N个游戏平台,金额上限V元,给出每个游戏平台的价钱和其上游戏数量;
每个游戏有一个花费及愉悦值,求在花费不超上限的情况下,最大的愉悦值。
(1 <= N <= 50)
(1 <= V <= 100,000)
每个游戏平台价格(1 <= P_i <= 1000)
每个平台游戏数量(1 <= G_i <= 10)
每个游戏价格(1 <= GP_j price <= 100)
游戏带来的愉悦值 (1 <= PV_j <= 1,000,000)
解析:
最开始想到方程为dp[i][j]={dp[i-1][j-x],dp[i-1][j]};
表示第i个平台花j元的最大愉悦值。
由于每次dp[i][j]求解都只会和它前一层也就是dp[i-1]一层有关系,所以很明显,可以采用滚动数组优化。
但是数组是什么含义,需要斟酌一下,我选择去掉表示游戏平台的i,剩下dp[i]表示当前花费为i的最大愉悦值。
但是我们发现,对于第i个平台,要么不取,要么取(废话)。
而每个平台在求解的过程中会干扰前边求过的最优值。
所以就可以分出一个数组用于求当前平台一定取的最优值,而另一个就代表全局的最优值。
code:
#include<bits/stdc++.h> using namespace std; const int MAXV =1e6+5; int n,V,dp[MAXV];//表示价钱为i时的最高产奶量; int dp2[MAXV];//表示第当前游戏平台一定取并价钱为i时的最高产奶量 int main() { cin>>n>>V; for(int i=0;i<=V;i++)dp[i]=0;//表示价钱为i时的最高产奶量 for(int i=1;i<=n;i++){//处理到第i个游戏平台 int temp,k; cin>>temp>>k; for(int c=temp;c<=V;c++)dp2[c]=dp[c-temp];//初始化成第i个平台当前只取了游戏主机的价钱 for(int j=1;j<=k;j++){ int p,v; cin>>p>>v; for(int c=V-p;c>=temp;c--) if(dp2[c+p]<dp2[c]+v)dp2[c+p]=dp2[c]+v; } for(int c=temp;c<=V;c++) if(dp[c]<dp2[c])dp[c]=dp2[c]; } cout<<dp[V]; return 0; }
加油!