home on the range——优化与图形动态规划

Home on the Range

 家的范围
农民约翰在一片边长是N (2 <= N <= 250)英里的正方形牧场上放牧他的奶牛。
(因为一些原因,他的奶牛只在正方形的牧场上吃草。)
遗憾的是,他的奶牛已经毁坏一些土地。( 一些1平方英里的正方形)
农民约翰需要统计那些可以放牧奶牛的正方形牧场(至少是2x2的,在这些较大的正方形中没有小于1x1的部分被分割毁坏)。
你的工作要在被供应的数据组里面统计所有不同的正方形放牧区域(>2x2)的个数。
当然,放牧区域可能是重叠。

PROGRAM NAME: range

INPUT FORMAT

第 1 行:

  N,牧区的边长。

第 2 到 n+1行:

N个没有空格分开的字符。

0 表示 "那一个区段被毁坏了";1 表示 " 准备好被吃"。

SAMPLE INPUT (file range.in)
6
101111
001111
111111
001111
101101
111001

OUTPUT FORMAT
输出那些存在的正方形的大小和个数,一种一行。

SAMPLE OUTPUT (file range.out)
2 10
3 4
4 1
 

程序最初思想:设置数字f[k][i][j],k为正方形边长,i和j是正方形右下角的顶点坐标。a[i][j]存储0-1矩阵。

1.初始化:f[1][i][j]=a[i][j].

2.然后判断f[k-1][i-1][j-1]可否得到(边长为k-1的小正方形),如果可以,再在该正方形周围加一圈,就

是边长为k的正方形。

3.再判断这一圈中是否有0,有则f[k][i][j]=0;否则f[k][i][j]=1.

思想没错,但是第三步不得不用循环逐一判断,显然效率不高。而且,这也不是典型的动态规划的算法。

动态规划:第二与第三步变成了:

if(f[k-1][i-1][j]&&f[k-1][i][j-1]&&f[k-1][i-1][j-1]&&f[k-1][i][j])

f[k][i][j]=1;

else f[k][i][j]=0;

也就是判断边长为k的正方形的四个角上边长为k-1的正方形能否得到。另外可以减维。

 

 

代码
   
     
1 #include < stdio.h >
2 #include < stdlib.h >
3 int f[ 251 ][ 251 ],n;
4 int sum[ 251 ] = { 0 };
5 char a[ 251 ];
6
7 int main(){
8 FILE * in , * out ;
9 in = fopen( " input6.txt " , " r " );
10 out = fopen( " output.txt " , " w " );
11 int i,j,k,x,flag;
12
13 fscanf( in , " %d " , & n);
14 for (i = 1 ;i <= n;i ++ )
15 {
16 fscanf( in , " %s " ,a);
17 for (j = 1 ;j <= n;j ++ )
18 f[i][j] = a[j - 1 ] - ' 0 ' ;
19 }
20
21 for (k = 2 ;k <= n;k ++ )
22 for (i = n;i >= k;i -- )————循环要倒写
23 for (j = n;j >= k;j -- )
24 {
25 if (f[i][j - 1 ] && f[i][j] && f[i - 1 ][j - 1 ] && f[i - 1 ][j])
26 {
27 f[i][j] = 1 ;
28 sum[k] ++ ;
29 }
30 else f[i][j] = 0 ;
31 }
32
33 for (i = 2 ;i <= n;i ++ )
34 if (sum[i])
35 fprintf( out , " %d %d\n " ,i,sum[i]);
36 fclose( in );
37 fclose( out );
38 return 0 ;
39 }
40

总结:需要认真思考如何优化程序;在找状态方面稍有进步。继续努力啊。

你可能感兴趣的:(动态规划)