问题描述
小U和小S正在玩一个有趣的骰子游戏。每个骰子都有固定数量的面数k
,每一面的点数分别是1到k。小U拥有n个骰子,每个骰子i的面数是 a_i
,摇到每一面的概率均为 1/a_i
。小S则有m个骰子,每个骰子j的面数是 b_j
,摇到每一面的概率均为 1/b_j
。
两人分别同时摇各自的骰子,并将摇出的点数相加,得分较高的一方获胜,得分相同则为平局。游戏只进行一次,没有重赛。现在小U想知道他获胜的概率是多少。你能帮他计算吗?(答案保留三位小数)
输入:
n
:小U的骰子数量m
:小S的骰子数量arrayN
:小U的每个骰子面数arrayM
:小S的每个骰子面数
约束条件:
n
,m
,k
为整数,数据范围 1 ≤n
,m
,k
≤ 25
测试样例
样例1:
输入:
n = 1, m = 3, arrayN = [8], arrayM = [2, 3, 4]
输出:0.255
样例2:
输入:
n = 2, m = 2, arrayN = [3, 4], arrayM = [3, 3]
输出:0.5
样例3:
输入:
n = 3, m = 1, arrayN = [2, 2, 2], arrayM = [4]
输出:0.844
#include <climits>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <vector>
using namespace std;
// 计算单个玩家的点数总和概率分布
map<int, double>
calculate_probability_distribution(const vector<int> &dice_faces) {
map<int, double> dp;
dp[0] = 1.0; // 初始状态,总和为0的概率为1
// 动态规划计算得分概率分布
for (int faces : dice_faces) {
map<int, double> new_dp;
for (const auto &[current_sum, count] : dp) {
for (int outcome = 1; outcome <= faces; outcome++) {
new_dp[current_sum + outcome] += count;
}
}
dp = new_dp;
}
// 归一化每个得分的概率
double total_outcomes = 0.0;
for (const auto &[key, value] : dp) {
total_outcomes += value;
}
for (auto &[key, value] : dp) {
value /= total_outcomes;
}
return dp;
}
double solution(int n, int m, vector<int> arrayN, vector<int> arrayM) {
// 小U和小S的得分概率分布
map<int, double> u_distribution = calculate_probability_distribution(arrayN);
map<int, double> s_distribution = calculate_probability_distribution(arrayM);
double u_win_probability = 0.0;
// 计算小U的胜率
for (const auto &[u_sum, u_prob] : u_distribution) {
double s_lose_probability = 0.0;
for (const auto &[s_sum, s_prob] : s_distribution) {
if (u_sum > s_sum) {
s_lose_probability += s_prob;
}
}
u_win_probability += u_prob * s_lose_probability;
}
// 保留三位小数
return round(u_win_probability * 1000) / 1000.0;
}
int main() {
// Add your test cases here
std::cout << (solution(1, 3, {8}, {2, 3, 4}) == 0.255) << std::endl;
std::cout << (solution(2, 2, {3, 4}, {3, 3}) == 0.5) << std::endl;
std::cout << (solution(3, 1, {2, 2, 2}, {4}) == 0.844) << std::endl;
return 0;
}