zoukankan      html  css  js  c++  java
  • 2017美团---网格走法数目

    题目描述

    有一个X*Y的网格,小团要在此网格上从左上角到右下角,只能走格点且只能向右或向下走。请设计一个算法,计算小团有多少种走法。给定两个正整数int x,int y,请返回小团的走法数目。

    输入描述:

    输入包括一行,逗号隔开的两个正整数x和y,取值范围[1,10]。

    输出描述:

    输出包括一行,为走法的数目。
    示例1

    输入

    3 2
    

    输出

    10

    题目链接:https://www.nowcoder.com/practice/e27b9fc9c0ec4a17a5064fb6f5ab13e4?tpId=85&tqId=29883&tPage=1&rp=1&ru=/ta/2017test&qru=/ta/2017test/question-ranking

    题解:利用深搜,很蒙蔽的过了,这段代码可以说是java版的深搜模板。只能往右和往下走,不用标记数组,穷举出所有的走法情况,并计算走法总数可得最终解。
     1 import java.io.BufferedReader;
     2 import java.io.IOException;
     3 import java.io.InputStreamReader;
     4 
     5 public class Main {
     6 
     7     public static void main(String[] args) throws IOException {
     8         BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
     9         String line = in.readLine();
    10         String[] pos = line.split(" ");
    11         int x = Integer.parseInt(pos[0]);
    12         int y = Integer.parseInt(pos[1]);
    13         int cnt = dfs(0, 0, x, y, 0);
    14         System.out.println(cnt);
    15     }
    16     public static int dfs(int x, int y, int end_x, int end_y, int cnt) {
    17         if(x == end_x && y == end_y) {
    18             cnt++;
    19             return cnt;
    20         }
    21         int res = 0;
    22         for(int i = 0; i < 2; i++) {//循环往右和往下走
    23             int next_x, next_y;
    24             if(i == 0) {//往下走
    25                 next_x = x + 1;
    26                 next_y = y;
    27             }
    28             else {//往右走
    29                 next_x = x;
    30                 next_y = y + 1;
    31             }
    32             if(next_x <= end_x && next_y <= end_y) {//只要不出边界,则进dfs
    33                 cnt = dfs(next_x, next_y, end_x, end_y, cnt);
    34             }
    35         }
    36         return cnt;
    37     }
    38 }
    View Code

    借鉴:

    法一:由裴波那挈数列引申出的dp思想,由于只能往右和往下走,所以这里有dp方程式:dp[m][n] = dp[m-1][n] + dp[m][n-1]。

     1         int[][] dp = new int[x + 1][y + 1];
     2         for(int i = 0; i <= x; i++) {//初始化
     3             dp[i][0] = 1;
     4         }
     5         for(int i = 0; i <= y; i++) {//初始化
     6             dp[0][i] = 1;
     7         }
     8         for(int i = 1; i <= x; i++) {
     9             for(int j = 1; j <= y; j++) {//穷举不需要判断if
    10                 dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
    11             }
    12         }
    13         System.out.println(dp[x][y]);
    View Code

    法二:为了节省上面dp数组的空间,这里直接用递归解决,思想还是上面的dp思想,可以从两个方向入手,第一个是从最初始到最终行和列,递归返回的时候是从最终行和列返回的;第二个是从最终行和列到最初始,递归返回的时候是从最初始返回的。但是两个的递归结束条件一定要用||连接,而不要用&&连接,因为||是为了防止出界。一旦任意一个坐标走到边界处就表示该return了。

    第一个:

    1     public static int dfs(int x, int y, int end_x, int end_y, int cnt) {
    2         if(x == end_x || y == end_y) {
    3             cnt++;
    4             return cnt;
    5         }
    6         else {
    7             return dfs(x + 1, y, end_x, end_y, cnt) + dfs(x, y + 1, end_x, end_y, cnt);
    8         }
    9     }
    View Code

    第二个:

    1     public static int dfs(int x, int y) {
    2         if(x == 0 || y == 0) {
    3             return 1;
    4         }
    5         else {
    6             return dfs(x - 1, y) + dfs(x, y - 1);
    7         }
    8     }
    View Code
  • 相关阅读:
    WordPress修改后台登录地址
    android开发之浅谈viewpager
    android开发之viewpager and Fragment
    android开发之 广播机制
    android开发之 SQLite(数据库)
    前端目标——天猫网页
    android 开发之Toast
    centos8 单机安装k8s
    mysql 查看库大小
    idea 常见问题
  • 原文地址:https://www.cnblogs.com/cing/p/8033691.html
Copyright © 2011-2022 走看看