蘑菇阵(动态规划、百度)——unique paths
2016-04-24 13:28
381 查看
题目描述
现在有两个好友A和B,住在一片长有蘑菇的由n*m个方格组成的草地,A在(1,1),B在(n,m)。现在A想要拜访B,由于她只想去B的家,所以每次她只会走(i,j+1)或(i+1,j)这样的路线,在草地上有k个蘑菇种在格子里(多个蘑菇可能在同一方格),问:A如果每一步随机选择的话(若她在边界上,则只有一种选择),那么她不碰到蘑菇走到B的家的概率是多少?
输入描述:
第一行N,M,K(2 ≤ N,M ≤ 20, k ≤ 100),N,M为草地大小,接下来K行,每行两个整数x,y,代表(x,y)处有一个蘑菇。
输出描述:
输出一行,代表所求概率(保留到2位小数)
输入例子:
2 2 1
2 1
输出例子:
0.50
解题思路:
题目要求的是不碰到蘑菇的概率,一开始我使用路径数的方法来求解的(p=不碰到蘑菇的走法/所有的走法),但是一直都未能通过所有测试。后来认真研究了下题目,也看了些网上的一些资料。题目要求要计算不碰到蘑菇的概率,因为走的概率不均等,如
2 3的蘑菇阵
1 2 3
4 5 6
从1 走到6
1-2的概率为0.5,2-3概率为0.5,3-6概率为1
1-4的概率为0.5,2-5概率为0.5,4-5概率为1,5-6概率为1,3-6概率为1
若走1-2-3-6概率为0.25,1-2-5-6概率为0.25,而走1-4-5-6的概率为0.5
所以三种走法的概率不均等,所以算其不碰到蘑菇的概率不可以用枚举路径数的方法计算。只能往两个方向走,所以两个方向的概率都是0.5,但是在边界处只有一种走法也就是该走法的概率为1,需要单独对边界进行处理。
不是边界的计算不碰到蘑菇的概率:
ways[i][j] = ways[i-1][j] * 0.5 * (map[i-1][j] + 1)%2+ ways[i][j-1] * 0.5 (map[i-1][j] + 1)%2 即为上面和左边的方向过来,前提上面和左边都没有蘑菇
边界的处理:
最底端第n行:ways[i][j] = ways[i][j-1] * (map[i-1][j] + 1)%2
最右边第m列:ways[i][j] = ways[i-1][j] * (map[i-1][j] + 1)%2
一开始我用路径求解的方法,该路径数方法也是一个动态规划的方法但不适合于蘑菇阵这个题目,将该方法稍微改改就是LeetCode里的两道动态规划题目unique paths和unique paths II
leetcode unique paths
稍微改改就是leetcode Unique Paths II 的解
现在有两个好友A和B,住在一片长有蘑菇的由n*m个方格组成的草地,A在(1,1),B在(n,m)。现在A想要拜访B,由于她只想去B的家,所以每次她只会走(i,j+1)或(i+1,j)这样的路线,在草地上有k个蘑菇种在格子里(多个蘑菇可能在同一方格),问:A如果每一步随机选择的话(若她在边界上,则只有一种选择),那么她不碰到蘑菇走到B的家的概率是多少?
输入描述:
第一行N,M,K(2 ≤ N,M ≤ 20, k ≤ 100),N,M为草地大小,接下来K行,每行两个整数x,y,代表(x,y)处有一个蘑菇。
输出描述:
输出一行,代表所求概率(保留到2位小数)
输入例子:
2 2 1
2 1
输出例子:
0.50
解题思路:
题目要求的是不碰到蘑菇的概率,一开始我使用路径数的方法来求解的(p=不碰到蘑菇的走法/所有的走法),但是一直都未能通过所有测试。后来认真研究了下题目,也看了些网上的一些资料。题目要求要计算不碰到蘑菇的概率,因为走的概率不均等,如
2 3的蘑菇阵
1 2 3
4 5 6
从1 走到6
1-2的概率为0.5,2-3概率为0.5,3-6概率为1
1-4的概率为0.5,2-5概率为0.5,4-5概率为1,5-6概率为1,3-6概率为1
若走1-2-3-6概率为0.25,1-2-5-6概率为0.25,而走1-4-5-6的概率为0.5
所以三种走法的概率不均等,所以算其不碰到蘑菇的概率不可以用枚举路径数的方法计算。只能往两个方向走,所以两个方向的概率都是0.5,但是在边界处只有一种走法也就是该走法的概率为1,需要单独对边界进行处理。
不是边界的计算不碰到蘑菇的概率:
ways[i][j] = ways[i-1][j] * 0.5 * (map[i-1][j] + 1)%2+ ways[i][j-1] * 0.5 (map[i-1][j] + 1)%2 即为上面和左边的方向过来,前提上面和左边都没有蘑菇
边界的处理:
最底端第n行:ways[i][j] = ways[i][j-1] * (map[i-1][j] + 1)%2
最右边第m列:ways[i][j] = ways[i-1][j] * (map[i-1][j] + 1)%2
public static double getProbability(int map[][], int n, int m) { double ways[][] = new double [m];// 没走蘑菇阵的概率 ways[0][0] = 1; // int ti = 0, tj = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) {//注意处理单行和单列的问题 if (j == m - 1 && i - 1 >= 0) {// 最右边 ways[i][j] = ways[i - 1][j]; } if (i == n - 1 && j -1 >=0) {// 最下边 ways[i][j] += ways[i][j - 1]; } if(i - 1 >= 0)//不止一行 if (map[i - 1][j] != 1 && j != m - 1) {// 往下走的概率 ways[i][j] += ways[i - 1][j] * 0.5; } if (j-1 >= 0) {//不止一列 if (map[i][j - 1] != 1 && i != n - 1) {// 往右边走 ways[i][j] += ways[i][j - 1] * 0.5; } } if (map[i][j] == 1) {//如果终点是蘑菇则概率为0 ways[i][j] = 0; } } } if (map[n - 1][m - 1] == 1) { ways[n - 1][m - 1] = 0; } // show(ways, n, m); return ways[n - 1][m - 1]; }
一开始我用路径求解的方法,该路径数方法也是一个动态规划的方法但不适合于蘑菇阵这个题目,将该方法稍微改改就是LeetCode里的两道动态规划题目unique paths和unique paths II
/** * 用路径法求解概率=可以走的路径/总的路径,算了好久都是错的,因为走的路径概率不一样( ╯□╰ ) * * @param map * @param n * @param m * @return */ public static double getPathNumProbability(int map[][], int n, int m) { int ways[][][] = new int [m][3];// 0存储没有走蘑菇的,1存储走蘑菇的,2存储没考虑蘑菇的 ways[0][0][1] = 0; ways[0][0][0] = 1; ways[0][0][2] = 1; for (int i = 1; i < n; i++) {// 首列 ways[i][0][2] = 1; ways[i][0][0] = ways[i - 1][0][0]; ways[i][0][1] = ways[i - 1][0][1]; if (map[i - 1][0] == 1) { ways[i][0][1] = 1; ways[i][0][0] = 0; } } for (int j = 1; j < m; j++) {// 首行 ways[0][j][0] = ways[0][j - 1][0]; ways[0][j][1] = ways[0][j - 1][1]; ways[0][j][2] = 1; if (map[0][j - 1] == 1) { ways[0][j][1] = 1; ways[0][j][0] = 0; } } // int ti = 0, tj = 0; for (int i = 1; i < n; i++) { for (int j = 1; j < m; j++) { ways[i][j][2] = ways[i - 1][j][2];// 往下走 if (map[i - 1][j] == 1) { ways[i][j][1] = ways[i - 1][j][2]; ways[i][j][0] = 0; } else { ways[i][j][1] = ways[i - 1][j][1]; ways[i][j][0] = ways[i - 1][j][0]; } ways[i][j][2] += ways[i][j - 1][2];// 往右走 if (map[i][j - 1] == 1) { ways[i][j][1] += ways[i][j - 1][2]; ways[i][j][0] += 0; } else { ways[i][j][0] += ways[i][j - 1][0]; ways[i][j][1] += ways[i][j - 1][1]; } } } if (map[n - 1][m - 1] == 1) { ways[n - 1][m - 1][0] = 0; } // System.out.println("ways[n-1][m-1][2] "+ways[n-1][m-1][2]+" 00 // "+ways[n-1][m-1][0]+" 11 "+ways[n-1][m-1][1]); // show(ways,n,m); return ways[n - 1][m - 1][0] * 1.0 / ways[n - 1][m - 1][2]; }
leetcode unique paths
/** * * leetcode unique paths * A robot is located at the top-left corner of a m x n grid (marked 'Start' * in the diagram below). * * The robot can only move either down or right at any point in time. The * robot is trying to reach the bottom-right corner of the grid (marked * 'Finish' in the diagram below). * * How many possible unique paths are there? * * * Above is a 3 x 7 grid. How many possible unique paths are there? * * @param m * @param n * @return */ public int uniquePaths(int m, int n) { int map[][] = new int[m] ; int ways[][] = new int [m];// ways[0][0] = 1; for (int i = 1; i < n; i++) {// 首列 ways[i][0] = 1; } for (int j = 1; j < m; j++) {// 首行 ways[0][j] = 1; } // int ti = 0, tj = 0; for (int i = 1; i < n; i++) { for (int j = 1; j < m; j++) { ways[i][j] = ways[i - 1][j];// 往下走 ways[i][j] += ways[i][j - 1];// 往右走 } } return ways[n - 1][m - 1]; }
稍微改改就是leetcode Unique Paths II 的解
* leetcode Unique Paths II Follow up for "Unique Paths": * * Now consider if some obstacles are added to the grids. How many unique * paths would there be? * * An obstacle and empty space is marked as 1 and 0 respectively in the * grid. * * For example, There is one obstacle in the middle of a 3x3 grid as * illustrated below. * * [ [0,0,0], [0,1,0], [0,0,0] ] The total number of unique paths is 2. * * @param map * @param n * @param m * @return */ public int uniquePathsWithObstacles(int[][] obstacleGrid) { int n = obstacleGrid.length, m = obstacleGrid[0].length; int ways[][][] = new int [m][3];// 0存储没有走障碍的,1存储走障碍的,2存储没考虑障碍的 ways[0][0][1] = 0; ways[0][0][0] = 1; ways[0][0][2] = 1; for (int i = 1; i < n; i++) {// 首列 ways[i][0][2] = 1; ways[i][0][0] = ways[i - 1][0][0]; ways[i][0][1] = ways[i - 1][0][1]; if (obstacleGrid[i - 1][0] == 1) { ways[i][0][1] = 1; ways[i][0][0] = 0; } } for (int j = 1; j < m; j++) {// 首行 ways[0][j][0] = ways[0][j - 1][0]; ways[0][j][1] = ways[0][j - 1][1]; ways[0][j][2] = 1; if (obstacleGrid[0][j - 1] == 1) { ways[0][j][1] = 1; ways[0][j][0] = 0; } } // int ti = 0, tj = 0; for (int i = 1; i < n; i++) { for (int j = 1; j < m; j++) { ways[i][j][2] = ways[i - 1][j][2];// 往下走 if (obstacleGrid[i - 1][j] == 1) { ways[i][j][1] = ways[i - 1][j][2]; ways[i][j][0] = 0; } else { ways[i][j][1] = ways[i - 1][j][1]; ways[i][j][0] = ways[i - 1][j][0]; } ways[i][j][2] += ways[i][j - 1][2];// 往右走 if (obstacleGrid[i][j - 1] == 1) { ways[i][j][1] += ways[i][j - 1][2]; ways[i][j][0] += 0; } else { ways[i][j][0] += ways[i][j - 1][0]; ways[i][j][1] += ways[i][j - 1][1]; } } } if (obstacleGrid[n - 1][m - 1] == 1) { ways[n - 1][m - 1][0] = 0; } // System.out.println("ways[n-1][m-1][2] "+ways[n-1][m-1][2]+" 00 // "+ways[n-1][m-1][0]+" 11 "+ways[n-1][m-1][1]); // show(ways,n,m); return ways[n - 1][m - 1][0]; }
相关文章推荐
- ZOJ 3940 Modulo Query
- POJ 3061 Subsequence(尺取法)
- 人机交互设计之百度搜索软件评价
- The Product Managers’ Guide to Continuous Delivery and DevOps
- UML建模之时序图(Sequence Diagram)
- pcduino与Arduino串口通信
- STL源码笔记(12)—序列式容器之deque(二)
- Android常用UI之Toolbar
- runtime - UIButton点击事件重复处理
- pcduino上用opencv的能出现的问题+解决方案
- 隐藏UITableView的滚动条以及修改滚动条的颜色
- EasyUI-Datagrid二维表格:多表头
- 解决出现The FastCGI Handler was unable to process the request
- 【Arduino官方教程第一辑】示例程序 2-4 数字引脚上拉电阻
- qt quick与qt designer区别
- 1041. Be Unique (20)
- 微软拼音简捷关于人机交互设计的相关评价
- Selenium Webdriver重新使用已打开的浏览器实例
- 搜狗输入法关于人机交互设计相关评价
- suid sgid sticky-bit 三种特殊权限简介