正题

题目链接: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. Data-truncation--Incorrect-string-value

    修改表中,format_content 字段的字符集为utf8mb4 alter table 表名 modify column format_content longtext character se ...

  2. c#反射入门篇(Reflection)——MethodInfo 发现方法的属性

    网站:https://www.jianshu.com/p/52dc85668d00 也算记录自己的学习篇=.= 适合入门看 这里简单介绍下MethodInfo和他基本的几个方法 简介 MethodIn ...

  3. 图解Win 10 应用开发之Sqlite 数据库的简单用法

    尽管目前 UWP-RT 库中还没有自带操作Sqlite数据库的API,不过,真要使用的话也不难,因为通过 Nuget ,我们其实可以获取很多支持 Sqlite 操作的第三方组件,当然了,组件虽多,但不 ...

  4. mybatis学习日志之总结

    一.介绍mybatis MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名 ...

  5. Qt event()

    event() 今天要说的是 event()函数.记得之前曾经提到过这个函数,说在事件对象创建完毕后,Qt 将这个事件对象传递给 QObject的 event()函数.event()函数并不直接处理事 ...

  6. 网页前端video播放m3u8(HLS)

    网页前端video播放m3u8(HLS) HLS (HTTP Live Streaming)是Apple公司研发的流媒体传输技术,包括一个m3u8的索引文件.多个ts分片文件和key加密串文件.这项技 ...

  7. 【转】时冲的CSDN:Linux系统各个目录的作用

    请各位移步原文链接:时冲的CSDN 以下仅用于个人梳理,排版方便阅读记忆(原文更优): from my typora: 文章目录 Linux文件系统 LINUX有四种基本文件系统类型: 1.普通文件: ...

  8. springboot:嵌套使用异步注解@Async还会异步执行吗

    一.引言 在前边的文章<[springboot:使用异步注解@Async的那些坑>中介绍了使用@Async注解获取任务执行结果的错误用法,今天来分享下另外一种常见的错误. 二.代码演示 下 ...

  9. django1.9和mysql

    修改setting.py DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql',#使用mysql 'NAME': 'jiank ...

  10. 轻松搞定webpack5.x

    源码地址:https://gitee.com/cyp926/webpack-project.git "webpack": "^5.46.0", "we ...