[Usaco2010 Dec]Treasure Chest 藏宝箱

题目连接:点这里php

Solution:

刚开始觉得是博弈论,然而不是。。。c++

首先考虑n方dp,设f(l,r)为只有\(l\)\(r\)区间的钱的先手最大获利git

那么咱们能够获得式子f(l,r)=sum(l,r)-min(f(l+1,r),f(l,r-1)),表明取左仍是右数组

代码写出来是这样的:spa

for(int j=2;j<=n;j++)
        for(int i=j-1;i>=1;i--)
            f[i][j]=s[j]-s[i-1]-min(f[i+1][j],f[i][j-1]);

不过这道题卡空间,咱们能够发现第二维其实能够去掉(至关于滚动数组),而后直接dpcode

Code:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=5e3+1;
int n,f[N],s[N];
int read(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
    while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
    return x*f;
}
int main(){
    n=read();
    for(int i=1;i<=n;i++){
        f[i]=read();
        s[i]=s[i-1]+f[i];
    }
    for(int j=2;j<=n;j++)
        for(int i=j-1;i>=1;i--)
            f[i]=s[j]-s[i-1]-min(f[i+1],f[i]);
    printf("%d\n",f[1]);
    return 0;
}
相关文章
相关标签/搜索