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
原文地址:https://www.cnblogs.com/cing/p/8033691.html