HDU 1838 Chessboard
dp[i][j]表示以(i,j)为右下角所含棋盘的最大规模,
如果 s[i][j] == s[i-1][j-1] && s[i][j] != s[i-1][j] && s[i][j] != s[i][j-1] dp[i][j] = min( dp[i-1][j-1], dp[i-1][j], dp[i][j-1]) + 1
否则dp[i][j] = 1
1 //#define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 using namespace std; 7 8 int const maxn = 2000 + 5; 9 char map[maxn][maxn]; 10 int dp[maxn][maxn]; 11 12 int main(void) 13 { 14 #ifdef LOCAL 15 freopen("1838in.txt", "r", stdin); 16 #endif 17 18 int T; 19 scanf("%d", &T); 20 while(T--) 21 { 22 int n; 23 scanf("%d", &n); 24 int i, j; 25 for(i = 0; i < n; ++i) 26 scanf("%s", map[i]); 27 for(i = 0; i < n; ++i) 28 dp[0][i] = dp[i][0] = 1; 29 int size = 1, cnt = 0; 30 for(i = 1; i < n; ++i) 31 for(j = 1; j < n; ++j) 32 { 33 if(map[i][j] == map[i-1][j-1] && map[i][j] != map[i-1][j] 34 && map[i][j] != map[i][j-1]) 35 dp[i][j] = min(min(dp[i][j-1], dp[i-1][j]), dp[i-1][j-1]) + 1; 36 else dp[i][j] = 1; 37 if(map[i][j] == '1') 38 size = max(size, dp[i][j]); 39 } 40 41 for(i = 0; i < n; ++i) 42 for(j = 0; j < n; ++j) 43 if(dp[i][j] == size && map[i][j] == '1') 44 ++cnt; 45 printf("%d %d\n", size, cnt); 46 } 47 return 0; 48 }