zoukankan      html  css  js  c++  java
  • Luogu 1169 [ZJOI2007]棋盘制作

    Description

    给一个01矩阵, 求出最大的01交错的正方形和最大的01交错的矩阵

    Solution

    用动态规划求出最大的正方形, 用单调栈求出最大的矩阵。

    在这里仅介绍求出最大正方形(求最大矩阵 = 单调栈裸题  传送门 : 不会单调栈的同学可以去学

    定义数组$f[ i ][ j ]$ 为以$(i, j) $为右下角的正方形的边长

    $up[ i ][ j ]$ 表示从点$(i, j)$往上 $01$交错的长度

    $lef[ i ][ j ]$ 表示从点$(i, j)$往右$01$交错的长度

    当 $a[ i ][ j ] != a[i - 1][j - 1]$时才可由上一个正方形继续拓展, 否则长度 $f[ i ][ j ] = 1$

    于是有转移方程:

    $f[ i ][ j ] = 1$   $a[ i ][ j ] == a[i - 1][j - 1]$

    $f[ i ][ j ] = min(f[ i - 1][ j - 1] + 1, lef[ i ][ j ],  up[ i ][ j ])$     $ a[ i ][ j ] != a[i - 1][ j ]$

    Code

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define rd read()
     5 #define rep(i,a,b) for(register int i = (a); i <= (b); i++)
     6 #define per(i,a,b) for(register int i = (a); i >= (b); --i)
     7 #define R register
     8 using namespace std;
     9 
    10 const int N = 3e3;
    11 
    12 int n, m, a[N][N], pre[N], nxt[N], h[N], ans2;
    13 int lf[N][N], u[N][N], f[N][N], ans1;
    14 int st[N], tp;
    15 
    16 int read() {
    17     int X = 0, p = 1; char c = getchar();
    18     for(; c > '9' || c < '0'; c = getchar()) if(c == '-') p = -1;
    19     for(; c >= '0' && c <= '9'; c = getchar()) X = X * 10 +  c - '0';
    20     return X * p;
    21 }
    22 
    23 void work(int x) {
    24     rep(i, 1, m) pre[i] = 0, nxt[i] = m + 1;
    25     rep(i, 1, m)
    26         if(a[x][i] != a[x - 1][i]) h[i]++;
    27         else h[i] = 1;
    28     tp = 0;
    29     rep(i, 1, m) {
    30         int pr = 0;
    31         while(tp) {
    32             if(h[st[tp]] >= h[i]) tp--;
    33             else {
    34                 pr = st[tp]; break;
    35             }
    36         }
    37         pre[i] = pr;
    38         st[++tp] = i;
    39     }
    40     tp = 0;
    41     per(i, m, 1) {
    42         int nt = m + 1;
    43         while(tp) {
    44             if(h[st[tp]] >= h[i]) tp--;
    45             else {
    46                 nt = st[tp]; break;
    47             }
    48         }
    49         nxt[i] = nt;
    50         st[++tp] = i;
    51     }
    52     rep(i, 1, m) {
    53         int nt = nxt[i], pr = pre[i];
    54         rep(j, i + 1, nt)
    55             if(a[x][j] == a[x][j - 1]) {nt = j; break;}
    56         per(j, i - 1, pr)
    57             if(a[x][j] == a[x][j + 1]) {pr = j; break;}
    58         ans2 = max(ans2, (nt - pr - 1) * h[i]);
    59     }
    60 }
    61 
    62 int main()
    63 {
    64     n = rd; m = rd;
    65     memset(a, -1, sizeof(a));
    66     rep(i, 1, n) rep(j, 1, m) a[i][j] = rd;
    67     rep(i, 1, n) rep(j, 1, m) {
    68         f[i][j] = 1;
    69         if(a[i][j] != a[i][j - 1]) 
    70             lf[i][j] = lf[i][j - 1] + 1;
    71         else lf[i][j] = 1;
    72         if(a[i][j] != a[i - 1][j]) 
    73             u[i][j] = u[i - 1][j] + 1;
    74         else u[i][j] = 1;
    75         if(a[i][j] != a[i - 1][j - 1]) continue;
    76         f[i][j] = min(u[i][j], lf[i][j]);
    77         f[i][j] = min(f[i - 1][j - 1] + 1, f[i][j]);
    78         ans1 = max(ans1, f[i][j]);
    79     }
    80     printf("%d
    ", ans1 * ans1);
    81     rep(i, 1, n) work(i);
    82     printf("%d
    ", ans2);
    83 }
    View Code
  • 相关阅读:
    Mac实用快捷键大全
    Java 12 新特性概述
    java sdk官网直接下载地址
    使用SqlBulkCopy类实现导入excel表格
    框架页面高度自动刷新Javascript脚本
    从MyEclipse到IntelliJ IDEA ——让你脱键盘,全键盘操作
    带你走进EJB--将EJB发布为Webservice(1)
    带你走进EJB--将EJB发布为Webservice(2)
    poj 3042 Grazing on the Run
    算法导论:比较排序算法笔记
  • 原文地址:https://www.cnblogs.com/cychester/p/9577963.html
Copyright © 2011-2022 走看看