luogu 3004 宝箱

题目游戏的加强版,建议先去A掉(双倍经验),数据范围比较大,所以我们不能想原来那样开二维数组来储存,所以我们必须压维,现在我们重新定义状态,一维数组dp[i]表示以i开头的最优拿法。

做法:枚举每一种区间长度i,大区间是由小区间得来,所以正序枚举区间长度,枚举左端点j:

若下一步取左端点:dp[i]=sum[i+j]-sum[j-1]-dp[j+1].

若下一步取右端点:dp[i]=sum[i+j]-sum[j-1]-dp[j].

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
#define N int(1e5+2)
#define M int(1e5+2)
int n,a[N],dp[M],sum[M];
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        dp[i]=a[i],sum[i]=sum[i-1]+a[i];
    }
    for(int i=1;i<n;i++)
        for(int j=1;i+j<=n;j++)
            dp[j]=sum[i+j]-sum[j-1]-min(dp[j],dp[j+1]);
    printf("%d",dp[1]);
}
原文地址:https://www.cnblogs.com/rmy020718/p/9448993.html