AT abc303G - Bags Game
依据题意可以设计出一个区间 dp。由于先后手操作相同,所以可以只记先手得分的最大值。但是它是 \(\text O (n ^ 3)\) 的。
观察瓶颈转移形如 \(f _ {l, r} \leftarrow - f _ {i, j} + sum (l, r) - sum (i, j) - cost\),其中区间 \([i, j]\) 长度为定值,可以单调队列优化。
时间复杂度 \(\text O (n ^ 2)\)。
#include<cstdio>
#include<algorithm>
#define N 3005
using namespace std;
int n,A,B,C,D,a[N];
int lt,rt;
long long s[N],f[N][N],q[N],w[N];
void work(int m,int k,int c) {
lt=1,rt=0;
for(int i=k;i<=n;i++) {
w[i]=-f[i-k+1][i]-(s[i]-s[i-k]);
while(lt<=rt&&w[i]>=w[q[rt]]) rt--;
q[++rt]=i;
if(i>=m) {
if(lt<=rt&&q[lt]<i-m+k) lt++;
f[i-m+1][i]=max(f[i-m+1][i],w[q[lt]]+(s[i]-s[i-m])-c);
}
}
}
int main() {
scanf("%d%d%d%d%d",&n,&A,&B,&C,&D);
for(int i=1;i<=n;i++) scanf("%d",&a[i]),s[i]=s[i-1]+a[i];
for(int len=1;len<=n;len++) {
for(int l=1,r=len;r<=n;l++,r++) {
f[l][r]=max(-f[l+1][r]+a[l],-f[l][r-1]+a[r]);
}
work(len,max(len-B,0),A);
work(len,max(len-D,0),C);
}
printf("%lld\n",f[1][n]);
return 0;
}

浙公网安备 33010602011771号