news 2026/5/4 2:37:25

n个六面的骰子,扔一次之后和为k的概率是多少?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
n个六面的骰子,扔一次之后和为k的概率是多少?

题目要求:n个六面的骰子,扔一次之后和为k的概率是多少?给定骰子数量n和骰子的点数之和k,求概率res。

思路:动态规划dp。

问题分析:每个骰子的点数都是1~6,因此n个骰子的总点数和的范围是[n,6n],需要计算点数之和恰好等于k的方案数

1.确定dp数组及其下标的含义:dp[i][j]表示使用i个骰子,总点数和为j的方案数

2.确定递推公式:可知i个骰子的情况可以由i - 1个骰子的情况推出。

(1)因此dp[i][j] = dp[i - 1][j - 6] + dp[i - 1][[j - 5] + dp[i - 1][j - 4] + dp[i - 1][j - 3] + dp[i - 1][j - 2] + dp[i - 1][j - 1]。

(2)即:dp[i][j] = dp[i - 1][j - v] for v = 1 to 6

3.dp数组如何初始化:dp[0][0] = 1,表示使用0个骰子,总点数和为0的方案数为1。在这里没有实际意义,只用作dp数组的初始化。

4.确定遍历顺序:本题相当于分组背包问题。有n个组(每组对应一个骰子),每组有6个物品(点数1~6),每组必须且只能选1个物品,求恰好凑成总重量k的方案数。因此在使用二维数组时,组内物品的遍历顺序无所谓

附代码:

class Solution { public String probabilityOfSum(int n, int k) { // 如果 k 不在可能范围内,概率为 0 if (k < n || k > 6 * n) { return "0"; } // dp[i][s]:i 个骰子,点数和为 j 的方案数 long[][] dp = new long[n + 1][6 * n + 1]; dp[0][0] = 1; // i个骰子 for (int i = 1; i <= n; i++) { // j表示i的骰子可能的点数和,范围为[i,6 * i] for (int j = i; j <= 6 * i; j++) { // v表示第i个骰子可选点数,范围为[1,6] for (int v = 1; v <= 6; v++) { // j - v要大于等于0,因为第i个骰子的可选的点数一定不能超过点数和,否则需要排除 if (j - v >= 0) { // 因为v会从1-6中取值,所以要把这6种可能累加 dp[i][j] += dp[i - 1][j - v]; } } } } // 总方案数 = 6^n long total = (long) Math.pow(6, n); // 可选方案数 = dp[n][k] long ways = dp[n][k]; // 约分 long g = gcd(ways, total); ways /= g; total /= g; return ways + "/" + total; } // 递归求最大公约数(欧几里得算法,即辗转相除法) private long gcd(long a, long b) { return b == 0 ? a : gcd(b, a % b); } }

ACM模式:

import java.util.Scanner; class Solution { public String probabilityOfSum(int n, int k) { // 如果 k 不在可能范围内,概率为 0 if (k < n || k > 6 * n) { return "0"; } // dp[i][s]:i 个骰子,点数和为 j 的方案数 long[][] dp = new long[n + 1][6 * n + 1]; dp[0][0] = 1; // i个骰子 for (int i = 1; i <= n; i++) { // j表示i的骰子可能的点数和,范围为[i,6 * i] for (int j = i; j <= 6 * i; j++) { // v表示第i个骰子可选点数,范围为[1,6] for (int v = 1; v <= 6; v++) { // j - v要大于等于0,因为第i个骰子的可选的点数一定不能超过点数和,否则需要排除 if (j - v >= 0) { // 因为v会从1-6中取值,所以要把这6种可能累加 dp[i][j] += dp[i - 1][j - v]; } } } } // 总方案数 = 6^n long total = (long) Math.pow(6, n); // 可选方案数 = dp[n][k] long ways = dp[n][k]; // 约分 long g = gcd(ways, total); ways /= g; total /= g; return ways + "/" + total; } // 递归求最大公约数(欧几里得算法,即辗转相除法) private long gcd(long a, long b) { return b == 0 ? a : gcd(b, a % b); } } public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); // 读取骰子个数 n 和目标和 k int n = scanner.nextInt(); int k = scanner.nextInt(); // 计算结果 Solution solution = new Solution(); String result = solution.probabilityOfSum(n, k); System.out.println(result); scanner.close(); } }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/4 2:31:25

IGBT技术解析:功率半导体的革命与应用

1. IGBT技术概述&#xff1a;功率半导体领域的革命性突破在电力电子领域&#xff0c;绝缘栅双极晶体管&#xff08;IGBT&#xff09;的出现彻底改变了高压大电流应用的技术格局。作为一名从事功率半导体设计十余年的工程师&#xff0c;我见证了IGBT从实验室原型到工业主流的全过…

作者头像 李华
网站建设 2026/5/4 2:22:27

OmniPermission:基于RBAC扩展的Spring Boot权限管理实战指南

1. 项目概述与核心价值最近在搞一个需要处理复杂权限的Web应用&#xff0c;后台管理模块涉及到用户、角色、菜单、部门、数据范围&#xff0c;还有各种细粒度的操作按钮权限&#xff0c;光是想想怎么设计数据库表就头大。更别提前后端联调时&#xff0c;权限校验逻辑不一致导致…

作者头像 李华
网站建设 2026/5/4 2:19:29

流程化爬虫框架claw-flow:构建可编排、可监控的数据采集流水线

1. 项目概述与核心价值最近在和一些做数据采集和自动化流程的朋友交流时&#xff0c;大家普遍提到一个痛点&#xff1a;市面上很多爬虫框架要么太重&#xff0c;学习成本高&#xff1b;要么太轻&#xff0c;功能单一&#xff0c;一旦遇到复杂的采集逻辑、反爬策略或者需要将采集…

作者头像 李华
网站建设 2026/5/4 2:19:24

Arm Cortex-A76处理器架构特性与常见错误解析

1. Cortex-A76处理器架构特性与常见错误概述 Arm Cortex-A76作为一款高性能64位处理器核心&#xff0c;广泛应用于移动计算和嵌入式领域。其采用超标量乱序执行架构&#xff0c;支持三发射流水线设计&#xff0c;最高主频可达3GHz。在内存子系统方面&#xff0c;A76配备了64KB …

作者头像 李华