Luogu P4734 [BalticOI 2015]Hacker
Link
结论\(1\):能够选的电脑数为\(\lfloor\frac{n+1}2\rfloor\)。
结论\(2\):若先手先选了\(x\),那么后手可以让先手最后选到的电脑的左端点为\([x-\lfloor\frac{n+1}2\rfloor,x]\)中的任意一个。这可以采用模仿策略做到。
那么我们单调队列维护即可。
#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
const int N=1000007;
int read(){int x=0,c=getchar();while(isspace(c))c=getchar();while(isdigit(c))(x*=10)+=c&15,c=getchar();return x;}
int a[N],f[N],q[N];
int main()
{
int n=read(),m=(n+1)/2,ans=0;
for(int i=1;i<=n;++i) a[i]=read();
memcpy(a+n+1,a+1,n<<2);
for(int i=1,s=0;i<=n+m-1;++i)
{
if(s+=a[i],i>m) s-=a[i-m];
if(i>=m) f[i-m+1]=s;
}
memcpy(f+n+1,f+1,n<<2);
for(int i=1,l=0,r=0;i<=n+m-1;++i)
{
while(l<=r&&q[l]<=i-m) ++l;
while(l<=r&&f[q[r]]>=f[i]) --r;
if(q[++r]=i,i>=m) ans=std::max(ans,f[q[l]]);
}
printf("%d",ans);
}