E. Nanosoft (pretreatment, three-dimensional dp)

Title: Portal

Meaning of the questions: 

   The logo is defined Nanosoft four identical square size into one large square. The upper left corner is red, the upper right corner is green, the bottom left is yellow, the lower right corner is blue.

   These are for example the following

   

   These are not the

 

 

 

 

 

 

    You give a n * m matrix, the matrix of four capital letter "R", "G", "Y", "B" configuration, four capital letters represent the red, green, yellow, blue.

      There are times query Q, each inquiry, two input coordinates, (x1, y1), (x2, y2) representative (x1, y1) coordinates for the upper left corner of the matrix, (x2, y2) is the coordinates of the lower right corner of the matrix the matrix, can be used as a logo Nanosoft largest sub-matrix is.

 

answer: 

  First, define the pre [i] [j] [col] Representative matrix (1, 1), (i, j) in the color col how many grid, i.e. the prefix and a two-dimensional, this can be very simple pre-out . 

  Obviously, the logo can be used as Nanosoft must be square, and the side length must be an even number.

  Then define dp [i] [j] [k] as in (i, j) is the lower right corner of a square of k, the maximum side length of the square as a child can be a logo Nanosoft, also it is ( i - k + 1, j - k + 1) is the upper left corner, (i, j) is the lower right corner of the square, the side length of the square can be used as the sub-maximum value of the logo Nanosoft.

  Transfer equation is: dp [i] [j] [k] = max ({dp [i] [j] [k], dp [i] [j] [k - 1], dp [i - 1] [j ] [k - 1], dp [i] [j - 1] [k - 1], dp [i - 1] [j - 1] [k - 1]});

  We also determined in o (1) time to (i, j) is the lower right corner coordinates, a side length of whether k square energy throughout a logo Nanosoft, and can, then dp [i] [j] [k ] is a k.

  Then for each query, we know that the maximum side length of a square is min (x2 - x1 + 1, y2 - y1 + 1);

  Then we can enumerate this square. Up each query are enumerated max (n, m) times, that is, the complexity of the n * q would not timeout.

#include <bits/stdc++.h>
#define LL long long
#define mem(i, j) memset(i, j, sizeof(i))
#define rep(i, j, k) for(int i = j; i <= k; i++)
#define dep(i, j, k) for(int i = k; i >= j; i--)
#define pb push_back
#define make make_pair
#define INF INT_MAX
#define inf LLONG_MAX
#define PI acos(-1)
using namespace std;

const int N = 510;

char a[N][N];
char s[] = "RGYB";
int n, m, q;
int pre [N] [N] [ . 4 ]; /// third dimension, 0 for red, 1 for green, 2 for yellow, 3 for blue 
int DP [N] [N] [N]; 

int Check ( int Lux, int Luy, int RDX, int RDY, int COL) {
     return pre [RDX] [RDY] [COL] - pre [RDX] [Luy - . 1 ] [COL] - pre [Lux - . 1 ] [RDY] [ COL] + pre [Lux - . 1 ] [Luy - . 1 ] [COL]; 
} 

void the init () { 
    REP (K, 0 , . 3 ) REP (I, . 1 , n-) REP (J, . 1 , m)
        for [i] [j] [k]= To [i - 1 ] [j] [k] + to [i] [j - 1 ] [k] - to [i - 1 ] [j - 1 ] [k] + (a [i] [j] == p [k]); 
    Rep (i, 1 , n) rep (j, 1 , m) {
         for ( int a = 1 ; k <= min (i, j), k ++ ) {
             if (k% 2 == 0 ) {
                 int len = a / 2 ;
                if (check (i - only + 1 , j - only + 1 , i, j, 3 ) == * just as
                  && check (and - as + 1 , j - k + 1 , i, j - only, 2 ) == only * Only
                  && check (i - k + 1 , j - only + 1 , and - only, j, 1 ) == * just as
                  && check (i - k + 1 , j - k + 1 , and - only j - only, 0 ) == * only only) 
                    dp [i] [j] [k] = a; 
            } 
            Dp [i] [j] [k] = max ({dp [i] [j] [k], dp [i] [j] [k - 1 ], dp [i - 1 ] [j] [k - 1 ], dp [i] [j - 1][k - 1], dp[i - 1][j - 1][k - 1] });
        }
    }
}

int main() {

    scanf("%d %d %d", &n, &m, &q);
    rep(i, 1, n) scanf("%s", a[i] + 1);
    init();
    while(q--) {
        int x1, x2, y1, y2;
        scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
        int len = min(x2 - x1 + 1, y2 - y1 + 1);
        int ans = 0;
        if(x2 - x1 > y2 - y1) {
            int dis = (x2 - x1) -  (y2 - y1);
            rep(i, 0, dis) ans = max(ans, dp[x2 - i][y2][len]);
        }
        else {
            int dis = (y2 - y1) - (x2 - x1);
            rep(i, 0, dis) ans = max(ans, dp[x2][y2 - i][len]);
        }
        printf("%d\n", ans * ans);
    }
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/Willems/p/12307668.html