[BZOJ1057][ZJOI2007]棋盘制作(悬线法)
2016-11-07 22:55
302 查看
题目描述
传送门题解
设h(i,j)表示以(i,j)为下端点的悬线的最长长度,l(i,j)和r(i,j)分别表示使悬线有此长度的左边最近的限制和右边最近的限制。预处理L(i,j)R(i,j)分别表示点(i,j)能扩展到的最近的不合法点。
如果(i,j)与(i-1,j)颜色相同,那么h(i,j)=1,l(i,j)=L(i,j),r(i,j)=R(i,,j);
如果(i,j)与(i-1,j)颜色不相同,那么h(i,j)=h(i-1,j)+1,l(i,j)=max(l(i-1,j),L(i,j)),r(i,j)=min(r(i-1,j),R(i,j)).
矩形的答案即为max(h(i,j)*(r(ii,j)-l(i,j)-1)),正方形需要把长宽取一下min
代码
#include<iostream> #include<cstring> #include<cstdio> using namespace std; #define N 2005 int n,m,ans1,ans2; int a[N][N],L[N][N],R[N][N],l[N][N],r[N][N],h[N][N]; int main() { scanf("%d%d",&n,&m); for (int i=1;i<=n;++i) for (int j=1;j<=m;++j) scanf("%d",&a[i][j]); for (int i=1;i<=n;++i) { L[i][1]=0; for (int j=2;j<=m;++j) if (a[i][j]!=a[i][j-1]) L[i][j]=L[i][j-1]; else L[i][j]=j-1; R[i][m]=m+1; for (int j=m-1;j>=1;--j) if (a[i][j]!=a[i][j+1]) R[i][j]=R[i][j+1]; else R[i][j]=j+1; } for (int i=1;i<=m;++i) h[1][i]=1,l[1][i]=L[1][i],r[1][i]=R[1][i]; for (int i=2;i<=n;++i) { for (int j=1;j<=m;++j) if (a[i][j]==a[i-1][j]) { h[i][j]=1; l[i][j]=L[i][j],r[i][j]=R[i][j]; } else { h[i][j]=h[i-1][j]+1; l[i][j]=max(l[i-1][j],L[i][j]); r[i][j]=min(r[i-1][j],R[i][j]); } } for (int i=1;i<=n;++i) for (int j=1;j<=m;++j) { int len=min(h[i][j],r[i][j]-l[i][j]-1); if (len>0) ans1=max(ans1,len*len); ans2=max(ans2,h[i][j]*(r[i][j]-l[i][j]-1)); } printf("%d\n%d\n",ans1,ans2); }
相关文章推荐
- bzoj 1057: [ZJOI2007]棋盘制作 (dp+悬线法)
- BZOJ1057[ZJOI2007]棋盘制作 [单调栈]
- BZOJ 1057: [ZJOI2007]棋盘制作
- bzoj 1057: [ZJOI2007]棋盘制作 求最大全0/1矩阵(极大扩展矩阵)动态规划
- BZOJ 1057 ZJOI2007 棋盘制作 单调栈
- 【BZOJ 1057】 [ZJOI2007]棋盘制作
- [BZOJ1057][ZJOI2007]棋盘制作 单调栈
- BZOJ1057:[ZJOI2007]棋盘制作——题解
- bzoj 1057: [ZJOI2007]棋盘制作 单调栈
- bzoj1057: [ZJOI2007]棋盘制作(悬线法)
- BZOJ1057: [ZJOI2007]棋盘制作
- 【BZOJ 1057】 1057: [ZJOI2007]棋盘制作
- bzoj1057 [ZJOI2007]棋盘制作
- BZOJ 1057([ZJOI2007]棋盘制作-悬线法)
- bzoj 1057: [ZJOI2007]棋盘制作
- bzoj 1057: [ZJOI2007]棋盘制作
- bzoj 1057 [ZJOI2007] 棋盘制作 题解
- bzoj 1057: [ZJOI2007]棋盘制作
- [bzoj1057][ZJOI2007]棋盘制作
- 【BZOJ】1057: [ZJOI2007]棋盘制作(单调栈)