蘑菇阵

来源:互联网 发布:mac拼音写切换 编辑:程序博客网 时间:2024/04/28 11:58
问题描述:
* 现在有两个好友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(1 ≤ N,M ≤ 20, k ≤ 100),N,M为草地大小,
 * 接下来K行,每行两个整数x,y,代表(x,y)处有一个蘑菇。 
解题思路(DP):
问题表示:1.用map[N][M]表示n*m的草地,将有蘑菇的地方做上标记。
                   2.用P[i][j]来表示每个点不遇到蘑菇的概率。则原点概率显然为1。
问题的关键:如何利用P[0][0]一步步dp到终点n,m?    
我们可以把问题分类(主要是考虑边界):
     1.首先,对于第一行的点,它的前一个点只能来自左边。P[i][j-1]中存储了左边的点没有碰到蘑
        菇的概率。而对第一行来说,我们当前考察的这个左边点,选择走当前点这条路径的概率是0.
        5。因此,第一行的点P[i][j] = P[i][j - 1]*0.5。
     2.同理,第一列的点P[i][j] = P[i - 1][j] * 0.5。
     3.我们很清楚,不管是第一行还是第一列的点,他的前一个点总是有两种选择的,可以选左/
        右。但是某些点情况就不同了,他们就是走到最右边的和走到最下面的。
     4.对于走到最右边的点,P[i][j] = P[i - 1][j]*1.0 + P[i][j - 1]*0.5。
     5.上面的表达式其实对终点还不成立,我们可以将表达式优化为:
        p[i][j] = p[i - 1][j]* (j == m-1? 1.0:0.5) +
                 p[i][j - 1]* (i == n-1? 1.0:0.5);  
package nowcoder;import java.util.Scanner;/** * 现在有两个好友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(1 ≤ N,M ≤ 20, k ≤ 100),N,M为草地大小, * 接下来K行,每行两个整数x,y,代表(x,y)处有一个蘑菇。 *  * 特别提示:有蘑菇路径数/总路径数是不对的,因为每条路的概率不同。 *  * @ClassName: Mushroom * @Version 1.0  * @Copyright  * @date 2017年5月2日 下午1:40:16 * @description */public class Mushroom {public static void main(String[] args) {Scanner scan = new Scanner(System.in);int n,m,k;  //终点,B的家,k个蘑菇n = scan.nextInt();m = scan.nextInt();k = scan.nextInt();boolean map[][] = new boolean[n][m]; //地图int q = 0;while(q < k) {int x = scan.nextInt();int y = scan.nextInt();map[x -1][y-1] = true;  //此处有蘑菇q++;}scan.close();//动态规划,p[i][j]表示在i,j不遇到蘑菇的概率double p[][] = new double[n][m];p[0][0] = 1.0; //起点for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {//此处有蘑菇if(map[i][j] == true) {p[i][j] = 0;} else if(i==0 && j==0) { //起点不管continue;}else if(i== 0) {p[i][j] = p[i][j-1] * 0.5;} else if(j == 0) {p[i][j] = p[i-1][j] * 0.5;//i,j处无蘑菇,他前面也无蘑菇的概率,由上/左两条路决定//对于上面的路,如果它处于m-1列,则只能往下走,概率乘1//对于左边的路,如果他处于第n-1行,则只能往右走,概率乘1} else {p[i][j] = p[i - 1][j]* (j == m-1? 1.0:0.5) +  p[i][j - 1]* (i == n-1? 1.0:0.5);}}}System.out.println(String.format("%.2f",p[n-1][m-1]));}}


原创粉丝点击