题目连接:点这里php
刚开始觉得是博弈论,然而不是。。。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
#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; }