题解 P4563 【[JXOI2018]守卫】
本题的误导性极强,看到题大部分人都会去想凸包、单调栈一类的东西
显然的有这么一个事实:若游戏的区间是
于是我们确定右端点,然后可以从右往左扫,记
在扫的过程中,
考虑可见性判定,显然只要
就这样,做完了……如果想的方向对了真的非常简单
#include<bits/stdc++.h>
using namespace std;
const int N=5010;
int f[N][N],h[N],n;
double slope(int l,int r){return (double)(h[r]-h[l])/(r-l);}
bool cansee(int l,int x,int r){return slope(x,r)>slope(l,r);}
int main()
{
int ans=0;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",h+i);
for(int r=1;r<=n;r++)
{
ans^=(f[r][r]=1);
int sum=1,p=0;
for(int l=r-1;l>=1;l--)
{
if(!p||cansee(l,p,r)) sum+=min(f[l+1][p-1],f[l+1][p]),p=l;
ans^=(f[l][r]=sum+min(f[l][p-1],f[l][p]));
}
}
cout<<ans<<endl;
return 0;
}