• 62.Unique Paths---dp


    题目链接

    题目大意:给一个m*n的方格,从左上角走到右下角,中间无任何障碍,问有多少种走法。

    法一:DFS,超时,简单模板深搜,无任何剪枝,结果一半的数据超时。代码如下:

     1     public int uniquePaths(int m, int n) {
     2         int f[][] = {{0, 1}, {1, 0}};
     3         boolean vis[][] = new boolean[m][n];
     4         return dfs(m, n, 0, 0, 0, f, vis);
     5     }
     6     public static int dfs(int m, int n, int x, int y, int cnt, int f[][], boolean vis[][]) {
     7         if(x == m - 1 && y == n - 1) {
     8             System.out.println("answer:" + cnt);
     9             cnt++;
    10             return cnt;
    11         }
    12         for(int i = 0; i < 2; i++) {
    13             int cnt_x = x + f[i][0];
    14             int cnt_y = y + f[i][1];
    15             if(cnt_x < m && cnt_y < n && vis[cnt_x][cnt_y] == false) {
    16                 vis[cnt_x][cnt_y] = true;
    17                 cnt = dfs(m, n, cnt_x, cnt_y, cnt, f, vis);
    18                 vis[cnt_x][cnt_y] = false;
    19             }
    20         }
    21         return cnt;
    22     }
    View Code

    法二(借鉴):很简单的dp,dp[i][j]表示当终点坐标是[i,j]时,所有可能的路径总数代码如下(耗时1ms):

     1     public int uniquePaths(int m, int n) {
     2         int dp[][] = new int[m][n];
     3         //初始化
     4         //对于第一列和第一行,走的路径数应该初始化为1
     5         for(int i = 0; i < m; i++) {
     6             dp[i][0] = 1;
     7         }
     8         for(int i =0 ; i < n; i++) {
     9             dp[0][i] = 1;
    10         }
    11         //计算dp
    12         //对于dp[i][j],每一个坐标[i,j],都可以由其左侧和上侧走一步而来。类似于杨辉三角
    13         for(int i = 1; i < m; i++) {
    14             for(int j = 1; j < n; j++) {
    15                 dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
    16             }
    17         }
    18         return dp[m - 1][n - 1];
    19     }
    View Code

    法三(借鉴):一维dp,还不是很懂,是怎么来的,暂且记一下。代码如下(耗时0ms):

     1 public int uniquePaths(int m, int n) {
     2         int dp[] = new int[n];
     3         //初始化,dp[i]表示某一行第i列的路径总数
     4         for(int i = 0; i < n; i++) {
     5             dp[i] = 1;
     6         }
     7         //外层循环是每一行,第1行计算了,第2行就是利用了第1行的值,所以这里也是左+上的和得到当前值,只是节约了空间
     8         for(int i = 1; i < m; i++) {
     9             //对于每一行,逐一判定每一列的路径值。
    10             for(int j = 1; j < n; j++) {
    11                 dp[j] += dp[j - 1];
    12             }
    13         }
    14         //两层循环后,得到的最终的值就是所有路径的结果值。
    15         return dp[n - 1];
    16     }
    View Code

    法四(借鉴):数学方法,由左上到右下,向下要走m-1步,向右要走n-1步,也就是要走C(m+n-2, m-1)或C(m+n-2, n-1)步。而C(m, n) = A(m, n)/n!,又A(m, n)=m!/(m-n)!。则C(m+n-2, m-1)=m*(m+1)*(m+2)...*(m+n-2)/1*2*3...*(n-1)。代码如下:

    1     public int uniquePaths(int m, int n) {
    2         double res = 1;
    3                 //计算组合数
    4         for(int i = 1; i <= n - 1; i++) {
    5             res = res * (m + i - 1) / i;
    6         }
    7         return (int)res;
    8     }
    View Code
  • 相关阅读:
    使用Strust2框架写HelloWorld
    MyEclipse10搭建Strust2开发环境
    MyEclipse使用总结——在MyEclipse中设置jsp页面为默认utf-8编码
    HTML一些标签注意事项
    Spring常用注解
    VB.NET中Module的概念
    vs2008发布项目失败的解决方法
    Java开发中的一些小技巧
    DNS服务器
    关于在Struts2的Action中使用domain模型接收参数的问题
  • 原文地址:https://www.cnblogs.com/cing/p/8486002.html
Copyright © 2020-2023  润新知