为什么这么傻逼的题我还是写了这么久呢
设f[i][j]表示取到第i个硬币,上界是j的先手最大收益
然后就是枚举取多少来转移,但是这样是O(n)的,总复杂度就是n^3的了
考虑对于f[i][j-1]和f[i][j],f[i][j-1]选的范围是1~j-1,而f[i][j]是1~j,仅仅是多了一个转移的决策点
所以计算取j个和f[i][j-1]比较就解决了
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; const int _=1e2; const int maxn=2*1e3+_; int n,s[maxn]; int f[maxn][maxn]; int DP(int x,int y) { if(x==n+1)return 0; if(f[x][y]!=f[0][0])return f[x][y]; int i; if(y-1!=0)f[x][y]=DP(x,y-1); i=y;f[x][y]=max(f[x][y],(s[x+i-1]-s[x-1]) - DP(x+i,min(i*2,n-(x+i)+1)) ); return f[x][y]; } int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&s[i]),s[i]+=s[i-1]; memset(f,-63,sizeof(f)); int w=DP(1,2); printf("%d\n",(s[n]-w)/2+w); return 0; }