USACO3.34Home on the Range(DP)
之前做过一道类似的 国际象棋盘神马的。。
统计出以每个1作为右下角的最大正方形 那么以大于二到这个最大值之间为边的正方形都可以以这个为右下角 累加就可以了
dp[i][j] = min(dp[i-1][j],dp[i-1][j-1],dp[i][j-1])+1;
1 /* 2 ID: shangca2 3 LANG: C++ 4 TASK: range 5 */ 6 #include <iostream> 7 #include<cstdio> 8 #include<cstring> 9 #include<algorithm> 10 #include<stdlib.h> 11 using namespace std; 12 int dp[255][255],num[255]; 13 char s[255][255]; 14 int main() 15 { 16 freopen("range.in","r",stdin); 17 freopen("range.out","w",stdout); 18 int i,j,n; 19 cin>>n; 20 for(i = 1; i <= n ;i++) 21 for(j = 1; j <= n ; j++) 22 { 23 cin>>s[i][j]; 24 if(s[i][j]=='1') 25 dp[i][j] =1; 26 } 27 for(i = 2; i <= n ; i++) 28 { 29 for(j = 2 ; j <= n ; j++) 30 { 31 if(s[i][j]=='1'&&s[i-1][j]=='1'&&s[i-1][j-1]=='1'&&s[i][j-1]=='1') 32 dp[i][j] = min(min(dp[i-1][j],dp[i-1][j-1]),dp[i][j-1])+1; 33 } 34 } 35 for(i = 2; i <= n ; i++) 36 for(j = 2; j <= n ;j++) 37 { 38 for(int g = 2 ; g <= dp[i][j] ; g++) 39 num[g]++; 40 } 41 for(i = 2; i <= n ; i++) 42 if(num[i]) 43 cout<<i<<" "<<num[i]<<endl; 44 return 0; 45 }