其实这是个论文题我会乱说?
我大概是我见过的最简单的NOI题了吧
然而并没有用论文里的的方法(虽然是黑科技但是好麻烦啊)
这个东西嘛,很明显每次转移都是区域化的。
然后单调队列维护乱搞一下
代码写得好丑QAQ没治了
#include<cstdio> #include<cstring> #include<iostream> using namespace std; const int inf=1e9; int f[2][205][205],up[205][205][4]; int q[205],h,t,now,last; int n,m; char mp[205][205]; void push(int x){ while(h<=t&&q[t]<x)t--; q[++t]=x; } void pop(int x){ if(q[h]==x)h++; } void solve1(int l){ for(int j=1;j<=m;j++){ h=0;t=-1; int d=0,ed=n; for(int i=n;i>=1;i--){ d--;push(f[last][i][j]+d); if(mp[i][j]=='x'){ f[now][i][j]=-inf; continue; } int tmp=min(up[i][j][0],i+l); while(ed>tmp){ pop(f[last][ed][j]+d+ed-i); ed--; } f[now][i][j]=q[h]-d; } } } void solve2(int l){ for(int j=1;j<=m;j++){ h=0;t=-1; int d=0,ed=1; for(int i=1;i<=n;i++){ d--;push(f[last][i][j]+d); if(mp[i][j]=='x'){ f[now][i][j]=-inf; continue; } int tmp=max(up[i][j][1],i-l); while(ed<tmp){ pop(f[last][ed][j]+d+i-ed); ed++; } f[now][i][j]=q[h]-d; } } } void solve3(int l){ for(int i=1;i<=n;i++){ h=0;t=-1; int d=0,ed=m; for(int j=m;j>=1;j--){ d--;push(f[last][i][j]+d); if(mp[i][j]=='x'){ f[now][i][j]=-inf; continue; } int tmp=min(up[i][j][2],j+l); while(ed>tmp){ pop(f[last][i][ed]+d+ed-j); ed--; } f[now][i][j]=q[h]-d; } } } void solve4(int l){ for(int i=1;i<=n;i++){ h=0;t=-1; int d=0,ed=1; for(int j=1;j<=m;j++){ d--;push(f[last][i][j]+d); if(mp[i][j]=='x'){ f[now][i][j]=-inf; continue; } int tmp=max(j-l,up[i][j][3]); while(ed<tmp){ pop(f[last][i][ed]+d+j-ed); ed++; } f[now][i][j]=q[h]-d; } } } int main(){ //freopen("a.in","r",stdin); int x,y; scanf("%d%d%d%d",&n,&m,&x,&y); now=0;last=1; memset(f[now],-0x3f,sizeof(f[now])); f[now][x][y]=0; int k;scanf("%d",&k); for(int i=1;i<=n;i++) scanf("%s",mp[i]+1); for(int i=1;i<=n;i++){ up[i][m+1][2]=m; for(int j=m;j>=1;j--) if(mp[i][j]=='x')up[i][j][2]=j-1; else up[i][j][2]=up[i][j+1][2]; up[i][0][3]=1; for(int j=1;j<m;j++) if(mp[i][j]=='x')up[i][j][3]=j+1; else up[i][j][3]=up[i][j-1][3]; } for(int j=1;j<=m;j++){ up[n+1][j][0]=n; for(int i=n;i>=1;i--) if(mp[i][j]=='x')up[i][j][0]=i-1; else up[i][j][0]=up[i+1][j][0]; up[0][j][1]=1; for(int i=1;i<=n;i++) if(mp[i][j]=='x')up[i][j][1]=i+1; else up[i][j][1]=up[i-1][j][1]; } while(k--){ int si,ti,di;scanf("%d%d%d",&si,&ti,&di); now^=1;last^=1; if(di==1)solve1(ti-si+1); else if(di==2)solve2(ti-si+1); else if(di==3)solve3(ti-si+1); else solve4(ti-si+1); } int ans=0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) ans=max(ans,f[now][i][j]); printf("%d\n",ans); return 0; }
卧槽,下一篇论文讲的就是这个Σ( ° △ °|||)︴
好吧其实我想说的是我没用那个诡异的指针运算