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

 

 

你可能感兴趣的:(HDU)