题目:有一个m * n 的方格,如下图,一个小robot希望从左上角走到右下角,共有多少种不同的路线走法。
思路:
我的错误思路:全排列,从(0,0)走到(m - 1,n - 1)共需要往下走m-1步,往右走n-1步。那么计算公式就是(全排列(m-1+n-1)/(全排列(m-1)*全排列(n-1)))。想到这里我很happy的把全排列写好,submit, runtimeError。后面检测出是数值溢出了,即使使用long型数据接收全排列结果也会溢出。当然Java提供了BigInteger类帮助大数据的处理,但是这道理显然不是考察这个考点。故没有尝试BigInteger。
求助网络。第一道DP题,非常开心,当然我没有想出来,终于开始DP了。
对于任意一个目标点(假设到达这个点的路径有path_red条),如上图红框处,到达这个点都只有两条路,要么从上面的黑箭头下来(path_top),要么从左面的黑箭头过去(path_left),则可得到一个等式 path_red = path_top + path_left。核心公式就这个。
代码:
1、用最直观的回溯法:
1 int uniquePathsBackTrack(int m, int n) { 2 if(m==1 || n==1) return 1; 3 return uniquePaths(m-1, n) + uniquePaths(m, n-1); 4 }
这个会超时,我对回溯法不了解,不明白为什么会超时。
2、最标准的DP,没有丝毫的改进。AC了。
1 public int uniquePaths(int m, int n) { 2 if(m == 1 || n == 1) return 1; 3 4 int[][] path = new int[m][n]; 5 for(int i = 0 ; i < m ; i++) path[i][0] = 1; 6 for(int j = 0 ; j < n ; j++) path[0][j] = 1; 7 for(int i = 1 ; i < m ; i++){ 8 for(int j = 1 ; j < n ; j++){ 9 path[i][j] = path[i][j-1] + path[i-1][j]; 10 } 11 } 12 return path[m - 1][n - 1]; 13 }
还有很多对这个DP代码进行改进的,此处先放下,现在的理解不适合对DP过多纠缠。自由再回来复习的时候。