A Game hiho一下第173周

6 篇文章 0 订阅

题意: 小 ho 和小 hi 在玩游戏,给定一个数字串,每人每次从该串的开头或结尾选取一个数,直到选完为止,最后选取数字之和较大的那个人获胜。其中小 ho 先手。求小 ho 能获得的最大分数。

思路: 由样例可以看出,每次选取首尾中较大的数的这个贪心策略是错误的。
f[i][i] 表示对于 A[i,...,j] 数字串的先手能够获得的最大分数。
当 i==j 时,则 f[i][i]=A[i]
当 i < j 时,则先手可能选择 A[i] 或者 A[j] 。如果先手选择 A[i] ,则后手得到的数字串是 A[i+1,...,j] ,对应的后手能从该数字串中得到 f[i+1][j] 的最大分数。则后手肯定会按照能够获得最大分数的决策进行下一步选择,则此时先手能够获得的最大分数就是 k=i>jA[k]f[i+1][j] 。如果先手选择 A[j] 同理。
所以最终 f[i][j]=max(k=i>jA[k]f[i+1][j],k=i>jA[k]f[i][j1])

代码:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<stack>
#include<queue>
#include<utility>
#include<vector>
#include<cmath>
#include<set>
#include<map>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;

int N;
int A[1010];
int f[1010][1010];
int s[1010][1010];

int main()
{
    //freopen("in.txt", "r", stdin);
    while(scanf("%d", &N) == 1){
        for(int i=0; i<N; i++){
            scanf("%d", &A[i]);
        }

        for(int i=0; i<N; i++){
            for(int j=i; j<N; j++){
                if(i == j) s[i][j] = A[i];
                else{
                    s[i][j] = A[j]+s[i][j-1];
                }
            }
        }

        for(int i=0; i<N; i++){
            f[i][i] = A[i];
        }

        for(int len=2; len<=N; len++){
            for(int i=0; i+len-1<N; i++){
                int j = i+len-1;
                f[i][j] = s[i][j]-min(f[i+1][j], f[i][j-1]);
            }
        }

        printf("%d\n", f[0][N-1]);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值