【BZOJ5324】[JXOI2018]守衛(動態規劃)
阿新 • • 發佈:2019-02-23
動態 show com 時間復雜度 fin geo als https ++i 。
這樣子的時間復雜度就是\(O(n^2)\)的了。
【BZOJ5324】[JXOI2018]守衛(動態規劃)
題面
BZOJ
洛谷
題解
既然只能看到橫坐標在左側的點,那麽對於任意一個區間\([l,r]\)而言,\(r\)必須被選。
假設\(r\)看不到若幹個區間,其中一個區間是\([x,y]\),因為\(y+1\)能夠被看到,所以\([y+2,r]\)這一段一定看不到\([x,y]\)。因此\(y,y+1\)中必須要選擇一個。
先預處理出任意兩點之間能夠互相看到,這個東西的復雜度是\(O(n^2)\)的。
設\(f[l][r]\)表示區間\([l,r]\)的答案。
固定右端點,向左掃,每次求出當前的看不到的區間,那麽\(f[l][r]=1+\sum min(f[x][y],f[x][y+1])\)
這樣子的時間復雜度就是\(O(n^2)\)的了。
#include<iostream> #include<cstdio> using namespace std; #define MAX 5050 inline int read() { int x=0;bool t=false;char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')t=true,ch=getchar(); while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar(); return t?-x:x; } int n,ans,a[MAX],f[MAX][MAX]; bool g[MAX][MAX]; int main() { n=read(); for(int i=1;i<=n;++i)a[i]=read(); for(int i=1;i<=n;++i) for(int j=i-1,lst=0;j;--j) if(!lst||1ll*(a[i]-a[j])*(i-lst)<1ll*(a[i]-a[lst])*(i-j)) g[i][j]=g[j][i]=true,lst=j; for(int i=1;i<=n;++i) for(int j=i,s=1,lst=0;j;--j) { if(g[i][j]){if(!g[i][j+1])s+=min(f[j+1][lst],f[j+1][lst+1]);f[j][i]=s;} else{if(g[i][j+1])lst=j;f[j][i]=s+min(f[j][lst],f[j][lst+1]);} ans^=f[j][i]; } printf("%d\n",ans); return 0; }
【BZOJ5324】[JXOI2018]守衛(動態規劃)