[DP]Play Game

今天开始刷HackerRank。部分题解记录下。


题目:Play Game

链接:https://www.hackerrank.com/challenges/play-game


代码:

<pre name="code" class="cpp">#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int t,n;
long long num[100100];
long long sum[100100];
long long dp[100100];

int main(){
    cin>>t;
    while(t--){
        
        memset(sum,0,sizeof(sum));
        memset(dp,0,sizeof(dp));
        memset(num,0,sizeof(num));
        
        cin>>n;
        for(int i=0;i<n;i++){
            cin>>num[i];
        }
        
        for(int i=n-1;i>=0;i--){
            sum[i]=sum[i+1]+num[i];
        }
        
        dp[n-1]=sum[n-1];
        dp[n-2]=sum[n-2];
        dp[n-3]=sum[n-3];
        
        for(int i=n-4;i>=0;i--){
            dp[i] = sum[i]-min(min(dp[i+1],dp[i+2]),dp[i+3]);
        }
        
        cout<<dp[0]<<endl;
    }
}

思路:

1. 游戏的过程是从前向后的,即依次从i=0取到i=n-1。

2. dp的过程是从后向前的,即dp[i]表示先手A从i开始取,两人取完所有砖块后,先手A能取得的最大分数。

3. 值得注意的,这里的dp[i]表示从i开始取,使用最优策略能取得的最大分数。不区分先手A还是后手B。无论AB都会按照这个策略。原因是 有从i开始取到n-1的限制。

4. dp[i]的状态和dp[i+1],dp[i+2],dp[i+3]有关。从i开始取有3个选择,取1、2、3个。当这个人X取完j个后(j=1,2,3),下个人Y会在i+j位置开始,使用最优策略。下个人Y的之后的得分是dp[i+j]。这个人X的之后得分是Sum(i+j,n-1)-dp[i+j]。这个人X的在i位置的得分是dp[i]=Num(i,i+j)+Sum(i+j,n-1)-dp[i+j]=Sum(i,n-1)-dp[i+j]。选择j=1,2,3中的一个,使得dp[i]取最大值。&lt;/span&gt;&lt;span style=&quot;font-family: SimSun;&quot;&gt;最后dp[0]即为所求。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值