Gym-101502J Boxes Game (dp)

本文介绍了一种利用动态规划解决游戏策略问题的方法,通过计算玩家在游戏中的最优得分,展示了如何在一系列回合制游戏中,根据对手的行为预测并优化自身策略。文章详细解释了动态规划方程的设定和实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Ibraheem and Husam are playing a game with group of boxes, lined next to each other on a straight line, such that each box contains a card with some value written on it. Ibraheem and Husam already know the values of all cards before the game starts.

Ibraheem and Husam take turns to play the game, Ibraheem starts first. In each turn, a player can take one box from either ends of the line, add the value of the card inside this box to his score, then remove this box from the line.

Knowing that both players play optimally, your task is to calculate the value x - y, such that x is Ibraheem's score at the end of the game, and y is Husam's score at the end of the game.

Input

The first line contains an integer T (1 ≤ T ≤ 500), where T is the number of test cases.

The first line of each test case contains an integer n (1 ≤ n ≤ 103), where n is the number of boxes in the line.

The second line of each test case contains n integers a1, a2, ..., an ( - 103 ≤ ai ≤ 103), giving the values of the cards inside the boxes.

Output

For each test case, print a single line containing its answer.

Input

5
4
3 1 100 5
1
1000
4
-1 100 4 -5
1
-4
1
0

Output

97
1000
92
-4
0

  题解思路:

dp[x][y]表示在x到y上先手取得的最大值;

对于每一次取值,应考虑取得让对手取得min(dp[x-1][y],dp[x][y-1]),设sum为x到y的和;

所以动规方程 dp[x][y]=max(sum-dp[x+1][y],sum-dp[x][y-1]);

 

#include<bits/stdc++.h>

#define int long long
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long

using namespace std;

const int maxn=1e3+10;

int dp[maxn][maxn],vis[maxn][maxn],arr[maxn],a[maxn];

int dfs(int l,int r)
{
    if(vis[l][r]) return dp[l][r];
    vis[l][r]=1;
    if(l==r) return dp[l][r]=a[l];
    int l1=dfs(l+1,r);
    int r1=dfs(l,r-1);
    int sum=arr[r]-arr[l-1];
    return dp[l][r]=max(sum-l1,sum-r1);
}

#undef int
int main(){
#define int long long
    int t;
    scanf("%lld",&t);
    while(t--)
    {
        mem(dp,0);
        mem(vis,0);
        mem(arr,0);
        int n;
        scanf("%lld",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",a+i);
            arr[i]=arr[i-1]+a[i];
        }
        dfs(1,n);
        printf("%lld\n",2*dp[1][n]-arr[n]);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值