luoguP4457 [BJOI2018]治疗之雨 概率期望 + 高斯消元


应该是最后一道紫色的概率了....然而颜色啥也代表不了....
首先看懂题意:
你现在有$p$点体力,你的体力上限为$n$
在一轮中,
1.如果你的体力没有满,你有$\frac{1}{m + 1}$的几率回复一点体力
2.紧接着有$k$轮攻击,每轮攻击都有$\frac{1}{m + 1}$的几率使你掉一点体力
如果一轮后,你的体力$ \leq 0$,那么游戏结束
询问游戏结束的期望轮数
看懂题应该就懂了什么吧....
设状态$f[i]$表示生命值为$i$游戏结束的期望轮数
那么
$$f[i] = \begin{cases}
& 0\;\;(i = 0)\\
& 1 + \sum\limits_{j = 1}^i f[j] * P[i - j]\;\;(i = n)\\
& 1 + \sum\limits_{j = 1}^i f[j] * (\frac{P[i - j + 1]}{m + 1} + \frac{m * P[i - j]}{m + 1}) + f[i + 1]*\frac{P[0]}{m + 1} \;\;(else)
\end{cases}$$
其中,$P[i]$表示在一轮攻击中受到$i$点攻击的概率
($f[0]$结束游戏,因此不能向别的状态转移)
考虑怎么求$P[i]$
由于确定了$i$种要攻击,其余的不攻击,那么一种攻击方式的概率为$(\frac{1}{m + 1})^i * (\frac{m}{m + 1})^{k - i}$
对于攻击$i$次而言,总共有$C(k, i)$种攻击方式
因此$P[i] = C(k, i) *(\frac{1}{m + 1})^i * (\frac{m}{m + 1})^{k - i} $
直接$O(n^2)$暴力全部求出来...
那么,有了$P[i]$后,高斯消元的复杂度过高
但是,注意到方程中$0$的数量非常的多,因此在消元的时候把$0$项跳过
酱紫,复杂度就到$O($玄学$)$了,仔细优化一下就$O(n^2)$了,具体看代码吧....
注:记得判无解
注2:不知道为什么$P[]$数组莫名的要多预处理一些.....
注(注2):仿佛是$n = 0$的时候挂了.....出题人有猫病啊.....
复杂度$O(Tn^2)$,没怎么卡常
#include <cstdio>
using namespace std; extern inline char gc() {
static char RR[], *S = RR + , *T = RR + ;
if(S == T) fread(RR, , , stdin), S = RR;
return *S ++;
}
inline int read() {
int p = , w = ; char c = gc();
while(c > '' || c < '') { if(c == '-') w = -; c = gc(); }
while(c >= '' && c <= '') p = p * + c - '', c = gc();
return p * w;
} #define sid 1600
#define eid 200050
#define ri register int
const int mod = ; int n, p, m, k;
int inv[eid], P[sid], f[sid][sid]; void Init_Inv() {
inv[] = inv[] = ;
for(ri i = ; i <= ; i ++)
inv[i] = 1ll * (mod - mod / i) * inv[mod % i] % mod;
for(ri i = ; i <= ; i ++)
inv[i] = 1ll * inv[i - ] * inv[i] % mod;
} int fp(int a, int k) {
int ret = ;
for( ; k; k >>= , a = 1ll * a * a % mod)
if(k & ) ret = 1ll * ret * a % mod;
return ret;
} void Init_P() {
int invm = fp(fp(m + , mod - ), k);
for(ri i = ; i <= n + ; i ++) {
if(i > k) { P[i] = ; continue; }
int C = ;
for(ri j = k - i + ; j <= k; j ++) C = 1ll * C * j % mod;
C = 1ll * C * inv[i] % mod;
P[i] = 1ll * C * fp(m, k - i) % mod * invm % mod;
}
} void Init_Guass() {
int m11 = fp(m + , mod - );
int mm1 = 1ll * m * m11 % mod;
for(ri i = ; i <= n + ; i ++)
for(ri j = ; j <= n + ; j ++)
f[i][j] = ;
for(ri i = ; i < n; i ++) {
f[i][i] = ; f[i][n + ] = ;
f[i][i + ] = (mod - 1ll * P[] * m11 % mod);
for(ri j = ; j <= i; j ++) {
f[i][j] = (f[i][j] - 1ll * m11 * P[i - j + ] % mod + mod) % mod;
f[i][j] = (f[i][j] - 1ll * mm1 * P[i - j] % mod + mod) % mod;
}
}
f[n][n] = ; f[n][n + ] = ;
for(ri i = ; i <= n; i ++) f[n][i] = (f[n][i] - P[n - i] + mod) % mod;
} void Guass() {
for(ri i = ; i <= n; i ++) {
int inv = fp(f[i][i], mod - );
for(ri j = i + ; j <= n; j ++) {
int t = 1ll * f[j][i] * inv % mod;
for(ri k = i; k <= i + ; k ++)
f[j][k] = (f[j][k] - 1ll * f[i][k] * t % mod + mod) % mod;
f[j][n + ] = (f[j][n + ] - 1ll * f[i][n + ] * t % mod + mod) % mod;
}
}
for(ri i = n; i >= ; i --) {
f[i][n + ] = 1ll * f[i][n + ] * fp(f[i][i], mod - ) % mod;
f[i - ][n + ] = (f[i - ][n + ] - 1ll * f[i - ][i] * f[i][n + ] % mod + mod) % mod;
}
} int main() {
int Tt = read();
Init_Inv();
while(Tt --) {
n = read(); p = read(); m = read(); k = read();
if(k == ) { printf("-1\n"); continue; }
if(m == && k == ) { printf("-1\n"); continue; }
Init_P(); Init_Guass(); Guass();
int ans = f[p][n + ];
printf("%d\n", ans);
}
return ;
}
luoguP4457 [BJOI2018]治疗之雨 概率期望 + 高斯消元的更多相关文章
- [BZOJ5292][BJOI2018]治疗之雨(概率DP+高斯消元)
https://blog.csdn.net/xyz32768/article/details/83217209 不难找到DP方程与辅助DP方程,发现DP方程具有后效性,于是高斯消元即可. 但朴素消元显 ...
- BZOJ.3143.[HNOI2013]游走(概率 期望 高斯消元)
题目链接 参考 远航之曲 把走每条边的概率乘上分配的标号就是它的期望,所以我们肯定是把大的编号分配给走的概率最低的边. 我们只要计算出经过所有点的概率,就可以得出经过一条边(\(u->v\))的 ...
- [HNOI2011]XOR和路径 概率期望 高斯消元
题面 题解:因为异或不太好处理,,,因此按位来算,这样最后的答案就是每一位上的值乘对应的权值再求和.本着期望要倒退的原则,,,我们设$f[i]$表示从$i$到$n$,xor和为1的概率.那么观察$xo ...
- [HNOI2013] 游走 - 概率期望,高斯消元,贪心
假如我们知道了每条边经过的期望次数,则变成了一个显然的贪心.现在考虑如何求期望次数. 由于走到每个点后各向等概率,很显然一条边的期望次数可以与它的两个端点的期望次数,转化为求点的期望次数 考虑每个点对 ...
- 4.23 子串 AC自动机 概率期望 高斯消元
考虑40分. 设出状态 f[i]表示匹配到了i位还有多少期望长度能停止.可以发现这个状态有环 需要高斯消元. 提供一种比较简单的方法:由于期望的线性可加性 可以设状态f[i]表示由匹配到i到匹配到i+ ...
- BZOJ4820 SDOI2017硬币游戏(概率期望+高斯消元+kmp)
容易想到的做法是建出AC自动机,高斯消元.然而自动机上节点数量是nm的. 注意到我们要求的变量只有n个,考虑将其他不用求的节点合并为一个变量.这个变量即表示随机生成一个串,其不包含任何一个模板串的概率 ...
- UVA-10828 (概率期望+高斯消元)
题意: 给个有向图,每个节点等概率转移到它的后继节点,现在问一些节点的期望访问次数; 思路: 对于一个点v,Ev=Ea/d[a]+Eb/d[b]+Ec/d[c];a,b,c是v的前驱节点; 然后按这个 ...
- luoguP3232 [HNOI2013]游走 贪心 + 概率期望 + 高斯消元
首先,题目中的无向简单连通图代表着没有自环,重边... 总分的期望 = 每条边的期望之和...................每条边的期望又可以拆成$u \to v$的期望和$v \to u$的期望 ...
- 【BZOJ】3143: [Hnoi2013]游走 期望+高斯消元
[题意]给定n个点m条边的无向连通图,每条路径的代价是其编号大小,每个点等概率往周围走,要求给所有边编号,使得从1到n的期望总分最小(求该总分).n<=500. [算法]期望+高斯消元 [题解] ...
随机推荐
- [BZOJ 3039&洛谷P4147]玉蟾宫 题解(单调栈)
[BZOJ 3039&洛谷P4147]玉蟾宫 Description 有一天,小猫rainbow和freda来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地. ...
- 【洛谷 P4437】 [HNOI/AHOI2018]排列(贪心,堆)
题目链接 如果\(j<=k,a_{p[j]}!=p[k]\)可以理解为如果\(a_{p[j]}=p[k]\),那么\(k\)一定要放在\(j\)前面,也就是\(a_j\)在\(j\)前面. 于是 ...
- 去掉input获取focus时的边框
贴图,问题如下: 尽管已经设置输入框的border为none,当输入框focus时扔会出现浏览器自带的边框 解决方法,添加如下样式即可,.fs_input为输入框样式 ---------------- ...
- three.js_ "Failed to execute 'texImage2D' on 'WebGLRenderingContext': tainted canvases may not be loded."
这个报错是请求图片跨域了. 1.当我们使用thee.js的时候肯定会碰到利用各种请求去向服务器请求贴图. 2.假设我们获取的是图片在服务器上的路径然后我们用 加载贴图到这里都是没有问题当我们在贴图加载 ...
- Perl6多线程1 Thread : new / run
先看一个小例子: ) { #默认参数 say $name; } sub B(:name($name)) { #默认参数为 any say $name; } A(); A(); B(); B(name ...
- xss自动化攻击
所需工具 [1.xssValidator] [2.phantomjs] [3.xss.js] /** * This is a basic phantomJS script that will be u ...
- 工具===激活xmind 8
[下载jar包]: https://stormxing.oss-cn-beijing.aliyuncs.com/files/XMindCrack.jar 方法: 打开xmind 8 安装目录的 ...
- windows安装React Native开发运行环境
React Native是什么 React Native是facebook开源的一个用于开发app的框架.React Native的设计理念:既拥有Native (原生) 的用户体验.又保留React ...
- sqlserver如何添加全文索引
在SQL Server 中提供了一种名为全文索引的技术,可以大大提高从长字符串里搜索数 据的速度,不用在用LIKE这样低效率的模糊查询了. 下面简明的介绍如何使用Sql2008 全文索引 一.检查 ...
- C/C++——[04] 语句
在 C/C++语言中,语句以“ :”结束.某些情况下,一组语句在一起共同完成某一特定的功能,可以将它们用大括号括起来.我们称之为语句组.语句组可以出现在任何单个语句出现的地方. 1. 分支语句 一般情 ...