【BZOJ1047】[HAOI2007]理想的正方形(單調隊列,動態規劃)
阿新 • • 發佈:2018-09-29
geo cpp n) ace zoj != efi problem tchar
【BZOJ1047】[HAOI2007]理想的正方形(單調隊列,動態規劃)
題面
BZOJ
洛谷
題解
直接一個單調隊列維護一下沒給點和它前面的\(n\)個位置的最大值,再用一次單調隊列維護連續\(n\)列的,每個數和前面\(n\)個數的最大值,最小值同理,就做完了。
#include<iostream> #include<cstdio> using namespace std; #define MAX 1010 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 a,b,n,ans=2e9; int g[MAX][MAX]; int s[2][MAX][MAX]; int mx[MAX][MAX]; int Q[MAX],h,t; void get(int p) { for(int i=1;i<=a;++i) { h=1;t=0; for(int j=1;j<=b;++j) { while(h<=t&&j-Q[h]>=n)++h; while(h<=t&&g[i][Q[t]]<g[i][j])--t; Q[++t]=j;mx[i][j]=g[i][Q[h]]; } } for(int j=n;j<=b;++j) { h=1;t=0; for(int i=1;i<=a;++i) { while(h<=t&&i-Q[h]>=n)++h; while(h<=t&&mx[Q[t]][j]<mx[i][j])--t; Q[++t]=i;s[p][i][j]=mx[Q[h]][j]; } } } int main() { a=read();b=read();n=read(); for(int i=1;i<=a;++i) for(int j=1;j<=b;++j) g[i][j]=read(); get(0); for(int i=1;i<=a;++i) for(int j=1;j<=b;++j) g[i][j]=-g[i][j]; get(1); for(int i=n;i<=a;++i) for(int j=n;j<=b;++j) ans=min(ans,s[0][i][j]+s[1][i][j]); printf("%d\n",ans); return 0; }
【BZOJ1047】[HAOI2007]理想的正方形(單調隊列,動態規劃)