[HNOI2015] 亚瑟王 题解
前言
题目链接:洛谷。
题意简述
一套按顺序的
题目分析
状压 DP 可以拿到部分分,但是没有任何前途。
显然可以对计数视角转化,考虑每一张牌在这一局游戏中,被打出的概率
我们发现对于第一张牌
我不会求
考虑它没有被打出,当且仅当每一次考虑到它时,都以
或者有人将它理解为一个 01 序列,每一位独立且有
发现其他
接下来问题变成了如何求
出牌了。
从 转移而来。那么会有 次判定到 , 出牌的概率为 。 没有出牌。
从 转移而来。那么会有 次判定到 , 每次都不出的概率为 。
于是可以做到
代码
#include <cstdio> #include <iostream> using namespace std; const int N = 225; const double eps = 1e-13; int n, r, d[N]; double p[N]; double pw[N][N], f[N][N], P[N]; void solve() { scanf("%d%d", &n, &r); for (int i = 1; i <= n; ++i) scanf("%lf%d", &p[i], &d[i]); for (int i = 1; i <= n; ++i) { pw[i][0] = 1; for (int j = 1; j <= r; ++j) { pw[i][j] = pw[i][j - 1] * (1 - p[i]); f[i][j] = 0; } } f[1][0] = pw[1][r], f[1][1] = P[1] = 1 - f[1][0]; for (int i = 2; i <= n; ++i) for (int j = 0; j <= min(i, r); ++j) { f[i][j] = f[i - 1][j] * pw[i][r - j]; if (j) f[i][j] += f[i - 1][j - 1] * (1 - pw[i][r - j + 1]); } for (int i = 2; i <= n; ++i) { P[i] = 0; for (int j = 0; j <= min(i - 1, r); ++j) P[i] += f[i - 1][j] * (1 - pw[i][r - j]); } double ans = 0; for (int i = 1; i <= n; ++i) ans += P[i] * d[i]; printf("%.10lf\n", ans + eps); } signed main() { int t; scanf("%d", &t); while (t--) solve(); return 0; }
本文作者:XuYueming,转载请注明原文链接:https://www.cnblogs.com/XuYueming/p/18749450。
若未作特殊说明,本作品采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】