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

首先看懂题意:

你现在有$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. 数组与集合List的相互转化

    数组转化为集合 #此运用的是Arrays中的asList方法,返回一个List集合 *当数组元素为基本数据类型是把整个数组当作一个元素放入List集合中,代码举例: ,,}; List<int[ ...

  2. 【LibreOJ】#6257. 「CodePlus 2017 12 月赛」可做题2

    [题意]数列满足an=an-1+an-2,n>=3.现在a1=i,a2=[l,r],要求满足ak%p=m的整数a2有多少个.10^18. [算法]数论(扩欧)+矩阵快速幂 [题解]定义fib(i ...

  3. 查询timestamp类型数据

    $where=" roleid = 8 and lizhi = 0 and branchid IN (".implode(",",$ids).") a ...

  4. 26、Python的可变类型和不可变类型?

    Python的每个对象都分为可变和不可变 可变:列表.字典 不可变:数字.字符串.元祖 对不可变类型的变量重新赋值,实际上是重新创建一个不可变类型的对象,并将原来的变量重新指向新创建的对象(如果没有其 ...

  5. 通过cordova将vue项目打包为webapp

    准备工作:需要之前配置好vue-cli脚架构,安装好cordova环境.下面开始对vue.js项目进行打包,打包环境为Android. 可以看下我的github:https://github.com/ ...

  6. python3爬虫.4.下载煎蛋网妹子图

    开始我学习爬虫的目标 ----> 煎蛋网 通过设置User-Agent获取网页,发现本该是图片链接的地方被一个js函数代替了 于是全局搜索到该函数 function jandan_load_im ...

  7. 深入理解Spring系列之十一:SpringMVC-@RequestBody接收json数据报415

    转载 https://mp.weixin.qq.com/s/beRttZyxM3IBJJSXsLzh5g 问题原因 报错原因可能有两种情况: 请求头中没有设置Content-Type参数,或Conte ...

  8. flask插件系列之flask_session会话机制

    flask_session是flask框架实现session功能的一个插件,用来替代flask自带的session实现机制. 配置参数详解 SESSION_COOKIE_NAME 设置返回给客户端的c ...

  9. 设置网卡IP,还每次都挨个地址输入吗?批处理一下【转】

    1.设置网卡ip,子网掩码和默认网关,注意修改网卡名称,跟本地连接汇总的网卡名称保持一直 netsh interface ip set address "以太网" static 1 ...

  10. 2018-2019-2 网络对抗技术 20165301 Exp6 信息搜集与漏洞扫描

    2018-2019-2 网络对抗技术 20165301 Exp6 信息搜集与漏洞扫描 1.实践目标 掌握信息搜集的最基础技能与常用工具的使用方法. 2.实践内容 (1)各种搜索技巧的应用 (2)DNS ...