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;
}

加油!

posted @ 2019-08-11 22:01  yzhqwq  阅读(204)  评论(0编辑  收藏  举报