问题描述:
求一个n*m的网格内存在的矩形数目
例如:
1*1 有 1 个矩形:1个1*1的矩形
2*2 有 9 个矩形 :4个1*1的矩形,4个1*2的矩形,1个2*2的矩形
3*3 有多少个矩形??
。
。
。
思路一: 总数=a1个1*1的矩形+a2个1*2的矩形+....+b1个2*1的矩形+b2个2*2的矩形+...+x个n*m的矩形;
根据统计发现规律如下,n*m网格的矩形,包括
1*1的矩形 n*m个
1*2的矩形 n*(m-1)个
1*3的矩形 n*(m-2)个
.....
2*1的矩形 (n-1)*m 个
2*2的矩形 (n-1)*(m-1)个
....
算法一:
总数合计=n*m + n*(m-1) + n*(m-2)+....+(n-1)*m + (n-2)*(m-1)+...+)1
=n*(n+1)/2*(m*(m+1)/2)
=n*(n+1)*m*(m+1)/4
1
2
3
4 |
public
int Compute1( int
n, int
m) { return
n * (n + 1) * m * (m + 1) / 4; } |
算法二:
按照统计逻辑思路进行编写代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 |
public
int Compute2( int
_Width, int
_Height) { Dictionary< string , int > dic = new
Dictionary< string , int >(); for
( var
i = 1; i <= _Width; i++) { for
( var
j = 1; j <= _Height; j++) { var
sum = GetCount(i, j); dic.Add(i.ToString() + ","
+ j.ToString(), sum); _TotalCount = _TotalCount + sum; } } return
_TotalCount; } public
int GetCount( int
x, int
y) { if
(x == 1 && y == 1) { return
_Width * _Height; } else { return
(_Width - x + 1) * (_Height - y + 1); } } |
思路二:
动态规划,假设dp[i][j]表示以第 i 行第 j 列的格子为右下角顶点的矩形数目,那么dp[i][j] = 1 + dp[i-1][j] + dp[i][j-1] – dp[i-1][j-1] , 这里的1表示i ,j 位置的格子自身构成1*1的矩形,之所以减去dp[i-1][j-1], 因为dp[i-1][j] 和 dp[i][j-1] 都包含了dp[i-1][j-1]。计算时注意i = 1 和 j = 1的边界条件。最后把所有dp[i][j]加起来就是我们所求的答案。以3*3网格举例,为了计算方便,红色为设置的边界值,黑色的才是最后需要加起来的值(结果为36)
1
2
3
4
5
6
7
8
9
10
11
12
13 |
int rectNum( int
row, int
column) { vector<vector< int > >dp(row+1, vector< int >(column+1, 1)); int
res = 0; dp[0][0] = 2; for ( int
i = 1; i <= row; i++) for ( int
j = 1; j <= column; j++) { dp[i][j] = 1 + dp[i-1][j] + dp[i][j-1] - dp[i-1][j-1]; res += dp[i][j]; } return
res; } |
思路三:
我们假设网格是1行m列的,那么总的矩形数目 = m(1*1的矩形) + m-1(1*2的矩形) + m-2(1*3的矩形) +…+1(1*m的矩形) = m*(m+1)/2,同理n行1列总的矩形数目是n*(n+1)/2. 对于n*m的网格,我们可以先确定好选取的行数(即确定矩形的高),公共有n*(n+1)/2种选法,选好以后就可以压缩成1行m列的网格来考虑了,因此总共n*(n+1)/2*m*(m+1)/2个矩形。
1
2
3
4 |
int rectNum( int
row, int
column) { return
row*(row+1)*column*(column+1)/4; } |
原文:http://www.cnblogs.com/workformylove/p/3745037.html