[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;
}
相關文章
相關標籤/搜索