Unique Path

  参考文章:http://www.leetcode.com/2010/11/unique-paths.html

  题目描述:给定一个m×n的方格,求方格(1,1)到点(m,n)的路径条数。路径只能向右或向下走。

  文章中给出了三种算法:

  算法1:最容易想到的也是最原始的回溯搜索算法,递归实现回溯。

  算法2:由于在1回溯过程中,会做很多次重复计算。为了减少重复计算,使用动态规划中的备忘录算法,将已经计算出的值保存在数组中,使用这些值计算新的值。

  算法3:自底向上的动态规划算法,也是最简洁的算法。

  数学公式:高中排列组合的一道题,C(m+n-2,m-1)=C(m+n-2,n-1)

  代码如下:

View Code
 1 #include <iostream>
 2 #include <cassert>
 3 
 4 using namespace std;
 5 
 6 //纯粹的回溯算法
 7 int backtrack(int r,int c,int m,int n)
 8 {
 9     if (r==m && c==n)
10     {
11         return 1;
12     }
13     if (r>m || c>n)
14     {
15         return 0;
16     }
17     return backtrack(r+1,c,m,n)+backtrack(r,c+1,m,n);
18 }
19 
20 const int M_MAX=100;
21 const int N_MAX=100;
22 //使用dp备忘录改进回溯算法,减少重复计算
23 int dpbacktrack(int r,int c,int m,int n,int mat[][N_MAX+2])
24 {
25     if (r==m && c==n)
26     {
27         return 1;
28     }
29     if (r>m || c>n)
30     {
31         return 0;
32     }
33     if (mat[r+1][c]==-1)    //等于-1说明还没有计算过
34     {
35         mat[r+1][c]=dpbacktrack(r+1,c,m,n,mat);
36     }
37     if (mat[r][c+1]==-1)
38     {
39         mat[r][c+1]=dpbacktrack(r,c+1,m,n,mat);
40     }
41     return mat[r+1][c]+mat[r][c+1];
42 }
43 
44 int bt(int m,int n)
45 {
46     int mat[M_MAX+2][N_MAX+2];
47     for (int i=0;i<M_MAX+2;i++)
48     {
49         for (int j=0;j<N_MAX+2;j++)
50         {
51             mat[i][j]=-1;
52         }
53     }
54     return dpbacktrack(1,1,m,n,mat);
55 }
56 
57 //自底向上的dp算法
58 int dp(int m,int n)
59 {
60     int mat[M_MAX+2][N_MAX+2]={0};
61     mat[m][n+1]=1;
62     for (int r=m;r>=1;r--)
63     {
64         for (int c=n;c>=1;c--)
65         {
66             mat[r][c]=mat[r+1][c]+mat[r][c+1];
67         }
68     }
69     return mat[1][1];
70 }
71 
72 int main()
73 {
74     int m=7;
75     int n=4;
76     cout<<dp(m,n)<<endl;
77     cout<<bt(m,n)<<endl;
78     cout<<backtrack(1,1,m,n)<<endl;
79     return 0;
80 }

 

posted @ 2012-07-27 20:09  kasuosuo  阅读(252)  评论(0编辑  收藏  举报