正题

题目链接:https://www.luogu.com.cn/problem/P4457


题目大意

开始一个人最大生命值为\(n\),剩余\(hp\)点生命,然后每个时刻如果生命值没有满那么有\(\frac{1}{m+1}\)的概率回复一点生命,然后敌人攻击\(k\)次,每次有\(\frac{1}{m+1}\)概率造成一点伤害。

求期望多少次后生命值降到\(0\)或以下。

\(1\leq T\leq 100,1\leq n\leq 1500,1\leq m,k\leq 10^9\)


解题思路

\(dp\)方程还是很好推的,设\(p_i\)表示在敌人攻击时受到\(i\)点伤害的概率,那么就是

\[p_i=(\frac{1}{m+1})^i(\frac{m}{m+1})^{k-i}\binom{k}{i}
\]

的概率,这个\(i\)只需要计算到\(n\)就好了。

然后设\(f_i\)表示剩余\(i\)点生命时期望还需要打多久

然后枚举一个\(j\)表示本回合受到的伤害,分成回复了生命或者没有回复生命两种情况,方程就是

\[f_i=\frac{1}{m+1}(\sum_{j=0}^{i}p_jf_{i-j+1})+\frac{m}{m+1}(\sum_{j=0}^{i-1}p_jf_{i-j}+1)
\]

当然\(f_n\)需要特殊处理

\[f_n=\sum_{i=0}^np_if_{n-i}+1
\]

发现这个方程是有前有后的环状转移,但是暴力高斯消元\(O(n^3)\)的时间复杂度接受不了。

不难发现的是我们现在的方程矩阵其实就是一个下三角矩阵再往右扩一列。我们可以先\(O(n^2)\)把这个下三角消成对角线然后第\(i\)列就只有\(i\)和\(i+1\)两个系数了,反过来再消一次就好了。

时间复杂度\(O(Tn^2)\)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=1600,P=1e9+7;
ll T,n,hp,m,k,a[N][N],b[N];
ll inv[N],p[N];
ll power(ll x,ll b){
ll ans=1;
while(b){
if(b&1)ans=ans*x%P;
x=x*x%P;b>>=1;
}
return ans;
}
ll C(ll n,ll m){
ll ans=1;
for(ll i=n-m+1;i<=n;i++)ans=ans*i%P;
return ans*inv[m]%P;
}
signed main()
{
inv[1]=1;
for(ll i=2;i<N;i++)
inv[i]=P-(P/i)*inv[P%i]%P;
inv[0]=1;
for(ll i=1;i<N;i++)
inv[i]=inv[i-1]*inv[i]%P;
scanf("%lld",&T);
while(T--){
scanf("%lld%lld%lld%lld",&n,&hp,&m,&k);
ll invm=power(m+1,P-2);
if(!k||k==1&&!m){puts("-1");continue;}
else if(!m){
ll ans=0;
while(hp>0){if(hp<n)hp++;hp-=k;ans++;}
printf("%lld\n",ans);continue;
}
ll tmp=power(invm,k);
for(ll i=0;i<=min(k,n);i++)
p[i]=tmp*power(m,k-i)%P*C(k,i)%P;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
for(ll i=0;i<=min(k,n-1);i++)
a[n][n-i]=P-p[i];
a[n][n]++;b[n]++;
for(ll i=1;i<n;i++){
a[i][i]=1;b[i]=1;
for(ll j=0;j<=min(k,i-1);j++)
(a[i][i-j]+=P-invm*m%P*p[j]%P)%=P;
for(ll j=0;j<=min(k,i);j++)
(a[i][i-j+1]+=P-invm*p[j]%P)%=P;
}
for(ll i=1;i<=n;i++){
ll inv=power(a[i][i],P-2);
a[i][i]=1;b[i]=b[i]*inv%P;
a[i][i+1]=a[i][i+1]*inv%P;
for(ll j=i+1;j<=n;j++){
ll rate=P-a[j][i];a[j][i]=0;
(a[j][i+1]+=a[i][i+1]*rate)%=P;
(b[j]+=b[i]*rate)%=P;
}
}
for(ll i=n-1;i>=1;i--){
ll rate=P-a[i][i+1];
b[i]=(b[i]+rate*b[i+1])%P;
}
printf("%lld\n",(b[hp]+P)%P);
}
return 0;
}

P4457-[BJOI2018]治疗之雨【期望dp,高斯消元】的更多相关文章

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

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

  2. BZOJ_3143_[Hnoi2013]游走_期望DP+高斯消元

    BZOJ_3143_[Hnoi2013]游走_期望DP+高斯消元 题意: 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机 ...

  3. HDU 2262 Where is the canteen 期望dp+高斯消元

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2262 Where is the canteen Time Limit: 10000/5000 MS ...

  4. hdu4418 Time travel 【期望dp + 高斯消元】

    题目链接 BZOJ4418 题解 题意:从一个序列上某一点开始沿一个方向走,走到头返回,每次走的步长各有概率,问走到一点的期望步数,或者无解 我们先将序列倍长形成循环序列,\(n = (N - 1) ...

  5. 【noi2019集训题1】 脑部进食 期望dp+高斯消元

    题目大意:有n个点,m条有向边,每条边上有一个小写字母. 有一个人从1号点开始在这个图上随机游走,游走过程中他会按顺序记录下走过的边上的字符. 如果在某个时刻,他记录下的字符串中,存在一个子序列和S2 ...

  6. LightOJ 1151 Snakes and Ladders 期望dp+高斯消元

    题目传送门 题目大意:10*10的地图,不过可以直接看成1*100的,从1出发,要到达100,每次走的步数用一个大小为6的骰子决定.地图上有很多个通道 A可以直接到B,不过A和B大小不确定   而且 ...

  7. ZJUT 1423 地下迷宫(期望DP&高斯消元)

    地下迷宫 Time Limit:1000MS  Memory Limit:32768K Description: 由于山体滑坡,DK被困在了地下蜘蛛王国迷宫.为了抢在DH之前来到TFT,DK必须尽快走 ...

  8. Codeforces.24D.Broken robot(期望DP 高斯消元)

    题目链接 可能这儿的会更易懂一些(表示不想再多写了). 令\(f[i][j]\)表示从\((i,j)\)到达最后一行的期望步数.那么有\(f[n][j]=0\). 若\(m=1\),答案是\(2(n- ...

  9. HDU4418 Time travel(期望dp 高斯消元)

    题意 题目链接 Sol mdzz这题真的太恶心了.. 首先不难看出这就是个高斯消元解方程的板子题 \(f[x] = \sum_{i = 1}^n f[to(x + i)] * p[i] + ave\) ...

随机推荐

  1. Longhorn,企业级云原生容器分布式存储 - 定制默认设置

    内容来源于官方 Longhorn 1.1.2 英文技术手册. 系列 Longhorn 是什么? Longhorn 云原生容器分布式存储 - 设计架构和概念 Longhorn 云原生容器分布式存储 - ...

  2. 【springboot】过滤器、监听器、拦截器,Aspect切片

    转自: https://blog.csdn.net/cp026la/article/details/86501019 简介: 本章介绍拦截器.过滤器.切片对请求拦截的使用与区别,以及监听器在 spri ...

  3. WPF Tree多级绑定

    <Window x:Class="TreeTest.MainWindow" xmlns="http://schemas.microsoft.com/winfx/20 ...

  4. 【springcloud】服务熔断与降级(Hystrix)

    转自:https://blog.csdn.net/pengjunlee/article/details/86688858 服务熔断 服务熔断的作用类似于我们家用的保险丝,当某服务出现不可用或响应超时的 ...

  5. 三、vue前后端交互(轻松入门vue)

    轻松入门vue系列 Vue前后端交互 六.Vue前后端交互 1. 前后端交互模式 2. Promise的相关概念和用法 Promise基本用法 then参数中的函数返回值 基于Promise处理多个A ...

  6. Java事件模型

    1 import javax.swing.*; 2 import java.awt.event.*; 3 public class TestSourceListener { 4 5 public st ...

  7. rabbitMq镜像集群

    rabbitMq延迟投递的方案 1 把消息记录到数据路,通过定时器进行刷新 2 TTL 加上死信队列 :通过路由把过期的消息同步到死信队列,通过死信队列的消费者进行消费 3

  8. MySQL日志系统bin log、redo log和undo log

    MySQL日志系统bin log.redo log和undo log   今人不见古时月,今月曾经照古人. 简介:日志是MySQL数据库的重要组成部分,记录着数据库运行期间各种状态信息,主要包括错误日 ...

  9. 前端axios请求二进制数据流转换生成PDF文件空白问题(终极解决方案)

    本文章共1570字,预计阅读时间1 - 3分钟. 问题场景: axios请求二进制数据转换生成PDF空白问题,使用axios请求后端接口,后端返回的二进制流文件,需要转换成PDF,但是在postman ...

  10. Java并发之AQS原理解读(三)

    上一篇:Java并发之AQS原理解读(二) 前言 本文从源码角度分析AQS共享锁工作原理,并介绍下使用共享锁的子类如何工作的. 共享锁工作原理 共享锁与独占锁的不同之处在于,获取锁和释放锁成功后,都会 ...