Bob 的生存概率问题

作者:Grey

原文地址:

博客园:Bob 的生存概率问题

CSDN:Bob 的生存概率问题

题目描述

给定五个参数 n , m , i , j , k,表示在一个 n*m 的区域,Bob 处在 (i,j) 点,每次 Bob 等概率的向上、 下、左、右四个方向移动一步,Bob 必须走 k 步。如果走完之后,Bob 还停留在这个区域上, 就算 Bob 存活,否则就算 Bob 死亡。请求解 Bob 的生存概率,返回字符串表示分数的方式。

题目链接:牛客-Bob的生存概率

暴力解法

由于 Bob 可以向四个方向任意一个方向走 k 步,所以,Bob 可以选择走的路线总数是:4^k,即:4 的 k 次方。

接下来就是要求在 4 ^ k 总数中,哪些是存活下来的路线,定义如下递归函数

long process(int i, int j, int k, int n, int m)

递归含义表示:目前在 (i,j) 位置,还有 k 步要走,走完了如果还在棋盘中就获得1个生存点,返回总的生存点数。

接下来是 base case,如果越界了,直接返回 0,

        if (i < 0 || i == n || j < 0 || j == m) {return 0;}

表示没有生存机会,

如果没有越界,但是此时正好 k == 0,说明已经有一种存活路线了,返回 1,表示一种有效路线。

        if (i < 0 || i == n || j < 0 || j == m) {return 0;}// 没有越界,说明还在棋盘中,没有步数了,直接返回一种有效路线。if (k == 0) {return 1;}

接下来是普遍情况, Bob 在棋盘中,可以往四面八方走,即

        long up = process(i - 1, j, k - 1, n, m);long down = process(i + 1, j, k - 1, n, m);long left = process(i, j - 1, k - 1, n, m);long right = process(i, j + 1, k - 1, n, m);

上述表示四面八方走返回的有效路线,四个方向的有效路线之和,就是答案,即

return up + down + left + right;

递归函数的完整代码如下

    public static long process(int i, int j, int k, int n, int m) {if (i < 0 || i == n || j < 0 || j == m) {return 0;}// 还在棋盘中!if (k == 0) {return 1;}// 还在棋盘中!还有步数要走long up = process(i - 1, j, k - 1, n, m);long down = process(i + 1, j, k - 1, n, m);long left = process(i, j - 1, k - 1, n, m);long right = process(i, j + 1, k - 1, n, m);return up + down + left + right;}

由于最后的结果要返回最简的分数形式,所以假设有效路线是 X 种,所有可能的走法是 Y 种,那么返回的字符串是如下形式

return (X/gcd(X,Y)) + "/" + (Y/gcd(X,Y))

其中 gcd(X,Y) 就是利用辗转相除法得到 X,Y 的最大公约数

    public static long gcd(long m, long n) {return n == 0 ? m : gcd(n, m % n);}

暴力解法的完整代码如下

import java.util.Scanner;public class Main {public static String livePossibility1(int i, int j, int k, int n, int m) {return buildExp(process(i, j, k, n, m), (long) Math.pow(4, k));}// 目前在i,j位置,还有k步要走,走完了如果还在棋盘中就获得1个生存点,返回总的生存点数public static long process(int i, int j, int k, int n, int m) {if (i < 0 || i == n || j < 0 || j == m) {return 0;}// 还在棋盘中!if (k == 0) {return 1;}// 还在棋盘中!还有步数要走long up = process(i - 1, j, k - 1, n, m);long down = process(i + 1, j, k - 1, n, m);long left = process(i, j - 1, k - 1, n, m);long right = process(i, j + 1, k - 1, n, m);return up + down + left + right;}public static String buildExp(long m, long n) {return m / gcd(m, n) + "/" + n / gcd(m, n);}public static long gcd(long m, long n) {return n == 0 ? m : gcd(n, m % n);}public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();int m = sc.nextInt();int i = sc.nextInt();int j = sc.nextInt();int k = sc.nextInt();System.out.println(livePossibility1(i, j, k, n, m)); sc.close();}
}

超时

动态规划解 (可 AC)

根据上述暴力递归过程可知,递归函数有三个可变参数:i,j,k;所以,定义一个三维数组 dp,就可以把所有递归过程的中间值存下,根据 i,j,k 的可变范围,定义如下三维数组:

long[][][] dp = new long[n][m][k + 1];

根据暴力递归过程的 base case,可以初始化 dp 的某些位置的值

        long[][][] dp = new long[n][m][k + 1];for (int row = 0; row < n; row++) {for (int col = 0; col < m; col++) {dp[row][col][0] = 1;}}

接下来是普遍情况,通过暴力递归过程可知,dp[i][j][k]依赖以下四个位置的值

dp[i-1][j][k-1]

dp[i+1][j][k-1]

dp[i][j-1][k-1]

dp[i][j+1][k-1]

即:三维数组的每一层只依赖上一层的数据结果,而第一层的值已经初始化好了,所以可以根据第一层求第二层,依次求到最后一层,这个动态规划的思路类似:象棋中的马跳步问题
,不赘述。

动态规划的解完整代码如下

import java.util.Scanner;public class Main {public static String livePossibility2(int i, int j, int k, int n, int m) {long[][][] dp = new long[n][m][k + 1];for (int row = 0; row < n; row++) {for (int col = 0; col < m; col++) {dp[row][col][0] = 1;}}for (int rest = 1; rest <= k; rest++) {for (int r = 0; r < n; r++) {for (int c = 0; c < m; c++) {dp[r][c][rest] = pick(dp, n, m, r - 1, c, rest - 1);dp[r][c][rest] += pick(dp, n, m, r + 1, c, rest - 1);dp[r][c][rest] += pick(dp, n, m, r, c - 1, rest - 1);dp[r][c][rest] += pick(dp, n, m, r, c + 1, rest - 1);}}}return buildExp(dp[i][j][k], (long) Math.pow(4, k));}public static String buildExp(long m, long n) {return m / gcd(m, n) + "/" + n / gcd(m, n);}public static long gcd(long m, long n) {return n == 0 ? m : gcd(n, m % n);}public static long pick(long[][][] dp, int n, int m, int r, int c, int rest) {if (r < 0 || r == n || c < 0 || c == m) {return 0;}return dp[r][c][rest];}public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();int m = sc.nextInt();int i = sc.nextInt();int j = sc.nextInt();int k = sc.nextInt(); System.out.println(livePossibility2(i, j, k, n, m));sc.close();}
}

更多

算法和数据结构笔记

Bob 的生存概率问题相关推荐

  1. sklearn 相关性分析_用sklearn机器学习预测泰坦尼克号生存概率

    前言 本文为练手记录,适用于刚入门的朋友参照阅读练习,大神请绕道,谢谢! 阅读大约需要10分钟. 一.理解项目概况并提出问题 1.1 登陆官网查看项目概况 Titanic: Machine Learn ...

  2. tensorflow2.0——预测泰坦尼克号旅客生存概率(Keras应用实践)

    一.数据准备 1.导入相关的库 import tensorflow as tf import numpy as np import matplotlib.pyplot as plt import pa ...

  3. 使用统计学分析《鱿鱼游戏》中“玻璃垫脚石”的生存概率

    如果你要在鱿鱼游戏中玩玻璃垫脚石,你的会选择那个数字? <鱿鱼游戏>是最近很火的电影,在阅读本篇文章之前,我假设你已经看过这部剧集了.比赛中需要使用不同的策略才能获胜,比如第7集中的&qu ...

  4. 泰坦尼克号数据集_机器学习-预测泰坦尼克号生存概率

    一.项目背景概述 泰坦尼克号沉船是历史上最有名的沉船事件之一:1912年4月15日,在她的第一次航行中,泰坦尼克号与冰山相撞后沉没.船上乘客和机组人员2224名,其中1502人死亡.这场耸人听闻的悲剧 ...

  5. 泰坦尼克生存概率预测

    (https://github.com/hpchihuo/titanic) 项目背景:本项目从数据分析的角度,寻找与生存率项目相关的生存因素,建立逻辑回归模型预测tantic人员生存情况. 1.提出问 ...

  6. Nature论文解读 | 基于深度学习和心脏影像预测生存概率

    作者丨Peter 单位丨某基因科技公司生物信息工程师 研究方向丨生物信息 本文解读的文章来自今年 2 月份的 Nature 杂志新子刊 Machine Intelligence,标题为:Deep-le ...

  7. 囚犯生存概率引发的循环思考

    有一个囚犯,国王打算处决他,但仁慈的国王给了他一个生还的机会.现在摆在他面前有两个瓶子,一个里面装了50个白球,一个装了50个黑球,这个囚犯有一个机会可以随便怎样重新分配这些球到两个瓶子中(当然,要保 ...

  8. [算法入门笔记] 18. 动态规划

    动态规划往往是有套路的,但套路是建立在熟练的基础上的~ 文章目录 0 建议 1 机器人达到指定位置的方法数 1.1 暴力递归 1.2 记忆化搜索 1.3 动态规划 2 换钱的最少货币数 2.1 暴力递 ...

  9. 左神---基础提升笔记

    文章目录 哈希函数与哈希表等 1.设计RandomPool结构 2.详解布隆过滤器 位图: 3.详解一致性哈希原理---虚拟节点技术 有序表与并查集等 1.岛问题 2.并查集: 3.KMP算法 3.1 ...

最新文章

  1. 读秦小波《设计模式之禅》 -- 工厂模式
  2. python朋友圈为什么这么火-看我如何用Python发一个高逼格的朋友圈
  3. CSS background属性
  4. html中响应式查询,css 响应式(媒介查询)
  5. Python轻量级IDE推荐 -- Jupyter QTConosle
  6. 自动去除所有目录的隐藏属性的DOS命令
  7. PHP实现同服务器多个二级域名共享 SESSION
  8. python栈与队列的封装
  9. 删除IBASE component时遇到data_not_consistent的exception
  10. 计算机基础知识:什么是位、字节、字、KB、MB
  11. leetcode面试题 16.21. 交换和(二分查找)
  12. C# 调用IP库(QQWry.Dat)查询IP位置及自动升级IP库方法(附IP库下载地址及相关dll下载)...
  13. android仿大众点评,仿大众点评android源码
  14. zplane函数怎么用m文件调用_elastique.dll,下载,简介,描述,修复,等相关问题一站搞定_DLL之家...
  15. Sharepoint学习笔记---Linq to Sharepoint--增,删,改操作
  16. php调取 zabbix实时数据_Zabbix监控系统部署详细步骤
  17. matlab qpsk调制程序,MATLAB QPSK调制及解调.doc
  18. Echarts 柱状图设置颜色
  19. 外显子bed文件获取
  20. 《穿透:像社会学家一样思考》简述

热门文章

  1. Tool:Visio2016/Visio2019专业版64位中文下载、安装(图文教程)之详细攻略
  2. 10条网站易用性技巧
  3. linux12企业实战 -- 37zabbix企业微信通知配置
  4. Linux内核中的IPSEC实现2
  5. Flink 1.12.2 源码浅析 : JobGraph
  6. 语法分析器---预测分析程序
  7. addEventListener()
  8. USB扫码枪无焦点输入到指定页面、指定文件框中
  9. html中iframe标签的用法详解
  10. Python网络爬虫及数据可视化(软科中国大学专业排名|计算机科学与技术)