hdu1838Chessboard(DP)

http://acm.hdu.edu.cn/showproblem.php?pid=1838

其实原先不知道这题是DP 我都想不到DP去

想了想没思路 看了下题解 经典思路 :第n大的都是由第n-1大的推出来的

记录以a(i,j)为右下端所能构成的最大棋盘 若a[i-1][j]和a[i][j-1]都与它不同 而且a[i-1][j-1]与它相同 则dp[i][j] = min(dp[i-1][j],dp[i][j-1],dp[i-1][j-1])+1 之所以是最小 是因为它要保证能全部构成 如:

1011

0101

1010

0101

dp[4][4] 如果可以由dp[3][3]推的话 就错了 应该是由dp[3][4]推来

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stdlib.h>
 6 using namespace std;
 7 #define N 2010
 8 #define LL __int64
 9 char s[N][N];
10 int dp[N][N];
11 int main()
12 {
13     int i,j,k,n,t;
14     scanf("%d",&t);
15     while(t--)
16     {
17         memset(dp,0,sizeof(dp));
18         scanf("%d",&n);
19         for(i = 1 ;i <= n ;i++)
20         {
21             getchar();
22             for(j = 1 ; j <= n ; j++)
23             {
24                 scanf("%c",&s[i][j]);
25                 dp[i][j] = 1;
26             }
27         }
28         int maxz=0;
29         for(i = 2 ; i <= n ; i++)
30             for(j = 2 ; j <= n ; j++)
31             {
32                 if(s[i][j]!=s[i-1][j]&&s[i][j]!=s[i][j-1]&&s[i][j]==s[i-1][j-1])
33                 dp[i][j] = min(min(dp[i-1][j],dp[i][j-1]),dp[i-1][j-1])+1;
34                 if(s[i][j]=='1')
35                 maxz = max(dp[i][j],maxz);
36             }
37         LL num=0;
38         for(i = 1; i <= n ; i++)
39             for(j = 1 ; j <= n ; j++)
40             if(s[i][j]=='1'&&dp[i][j]==maxz)
41             num++;
42         cout<<maxz<<" "<<num<<endl;
43     }
44     return 0;
45 }
View Code

 

 

posted @ 2013-08-11 22:26  _雨  阅读(209)  评论(0编辑  收藏  举报