应该是最后一道紫色的概率了....然而颜色啥也代表不了....

首先看懂题意:

你现在有$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]治疗之雨 概率期望 + 高斯消元的更多相关文章

  1. [BZOJ5292][BJOI2018]治疗之雨(概率DP+高斯消元)

    https://blog.csdn.net/xyz32768/article/details/83217209 不难找到DP方程与辅助DP方程,发现DP方程具有后效性,于是高斯消元即可. 但朴素消元显 ...

  2. BZOJ.3143.[HNOI2013]游走(概率 期望 高斯消元)

    题目链接 参考 远航之曲 把走每条边的概率乘上分配的标号就是它的期望,所以我们肯定是把大的编号分配给走的概率最低的边. 我们只要计算出经过所有点的概率,就可以得出经过一条边(\(u->v\))的 ...

  3. [HNOI2011]XOR和路径 概率期望 高斯消元

    题面 题解:因为异或不太好处理,,,因此按位来算,这样最后的答案就是每一位上的值乘对应的权值再求和.本着期望要倒退的原则,,,我们设$f[i]$表示从$i$到$n$,xor和为1的概率.那么观察$xo ...

  4. [HNOI2013] 游走 - 概率期望,高斯消元,贪心

    假如我们知道了每条边经过的期望次数,则变成了一个显然的贪心.现在考虑如何求期望次数. 由于走到每个点后各向等概率,很显然一条边的期望次数可以与它的两个端点的期望次数,转化为求点的期望次数 考虑每个点对 ...

  5. 4.23 子串 AC自动机 概率期望 高斯消元

    考虑40分. 设出状态 f[i]表示匹配到了i位还有多少期望长度能停止.可以发现这个状态有环 需要高斯消元. 提供一种比较简单的方法:由于期望的线性可加性 可以设状态f[i]表示由匹配到i到匹配到i+ ...

  6. BZOJ4820 SDOI2017硬币游戏(概率期望+高斯消元+kmp)

    容易想到的做法是建出AC自动机,高斯消元.然而自动机上节点数量是nm的. 注意到我们要求的变量只有n个,考虑将其他不用求的节点合并为一个变量.这个变量即表示随机生成一个串,其不包含任何一个模板串的概率 ...

  7. UVA-10828 (概率期望+高斯消元)

    题意: 给个有向图,每个节点等概率转移到它的后继节点,现在问一些节点的期望访问次数; 思路: 对于一个点v,Ev=Ea/d[a]+Eb/d[b]+Ec/d[c];a,b,c是v的前驱节点; 然后按这个 ...

  8. luoguP3232 [HNOI2013]游走 贪心 + 概率期望 + 高斯消元

    首先,题目中的无向简单连通图代表着没有自环,重边... 总分的期望 = 每条边的期望之和...................每条边的期望又可以拆成$u \to v$的期望和$v \to u$的期望 ...

  9. 【BZOJ】3143: [Hnoi2013]游走 期望+高斯消元

    [题意]给定n个点m条边的无向连通图,每条路径的代价是其编号大小,每个点等概率往周围走,要求给所有边编号,使得从1到n的期望总分最小(求该总分).n<=500. [算法]期望+高斯消元 [题解] ...

随机推荐

  1. 【CodeForces】708 B. Recover the String 数学构造

    [题目]B. Recover the String [题意]找到一个串s,满足其中子序列{0,0}{0,1}{1,0}{1,1}的数量分别满足给定的数a1~a4,或判断不存在.数字<=10^9, ...

  2. 【BZOJ】4596: [Shoi2016]黑暗前的幻想乡

    [题意]给定n个点的无向完全图,有n-1个公司各自分管一部分路,要求所有公司都有修路的生成树数.n<=17. [算法]容斥原理+生成树计数(矩阵树定理) [题解]每个生成树方案是一个公司有无修路 ...

  3. eclipse启动项目

    今天做的任务不多,没有自己写代码,上午看了些文章,下午我司后台给配了配项目环境,全装C盘了..以后有我好受的.. 看着后台操作,修改了N多配置,tomcat.redis.zkServer..Nginx ...

  4. 生产环境手把手部署ERC20智能合约

    工具 rimex http://remix.ethereum.org/ metamask https://metamask.io/ ERC20 代码 https://github.com/OpenZe ...

  5. skb_reserve(skb,2)中的2的意义

    skb_reserve() skb_reserve()在数据缓存区头部预留一定的空间,通常被用来在数据缓存区中插入协议首部或者在某个边界上对齐.它并没有把数据移出或移入数据缓存区,而只是简单地更新了数 ...

  6. Linux用户密码期限修改

    今天有开发报故,sftp无法登录.检查服务都是正常的,之前3月份也出现过此问题,当时忙没有注意,现在看每3个月出现问题.这才想到是密码过期导致的. 先重置用户密码,发现过期日志为Oct 08, 201 ...

  7. python安装模块的时候报错error: command 'gcc' failed with exit status 1

    [情况] 在写Python代码的时候,需要用到psutil模块,需要安装. 但是在安装时,报错:error: command 'gcc' failed with exit status 1 [解决步骤 ...

  8. linux系统性能排查命令

    [top] 命令可以动态查看当前系统的资源情况,以及占用资源的命令列表 用法: - ctrl + c / q : 停止此命令运行 - c : 展示完整的命令 - [top -bn1]:可以不动态的展示 ...

  9. 苹果容器超出内容overflow滑动卡顿问题

    -webkit-overflow-scrolling:touch; 就这么一段代码,加载需要滚动的容器css样式中.因为苹果的硬件加速产生的后果....

  10. hdu 1846(巴什博弈)

    Brave Game Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...