正题

题目链接: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. flutter中存储键值对简单数据(相当于前端localstorage概念)

    首先需要安装一个官方推荐包: 1 dependencies: 2 flutter: 3 sdk: flutter 4 shared_preferences: any // 先获取 shared pre ...

  2. C++ 三数之和

    来自leecode做题时,发现的双指针用法,觉得挺有意思所以记录一下 链接:https://leetcode-cn.com/problems/3sum 题目: 给你一个包含 n 个整数的数组 nums ...

  3. Ant的使用(一)

    <?xml version="1.0" encoding="UTF-8"?> <project name="projectName& ...

  4. servlet初识servletConfig

    package day09; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; ...

  5. Python3-sqlalchemy-orm 创建多表关联表带外键

    #-*-coding:utf-8-*- #__author__ = "logan.xu" import sqlalchemy from sqlalchemy import crea ...

  6. (六)羽夏看C语言——函数

    写在前面   由于此系列是本人一个字一个字码出来的,包括示例和实验截图.本人非计算机专业,可能对本教程涉及的事物没有了解的足够深入,如有错误,欢迎批评指正. 如有好的建议,欢迎反馈.码字不易,如果本篇 ...

  7. LNMP zabbix 4.4 安装

    硬件配置需求 环境 平台 CPU/内存 数据库 硬盘 监控主机数 小型 CentOS 2CPU/1GB MySQL.InnoDB 普通 100 中型 CentOS 2CPU/2GB MySQL.Inn ...

  8. 洛谷P3130 haybalesCounting Haybale P 题解

    题目 [USACO15DEC]haybalesCounting Haybale P 题解 最近刚刚自学了线段树这个数据结构,恰巧做到了这道线段树的模板题.其实也没有什么好多说的,接触过线段树的大犇肯定 ...

  9. Spring(一)——概述

    一.概述 1.介绍 struts 是 web 框架 (jsp/action/actionfrom).hibernate是orm (Object Relational Mapping) 框架,处于持久层 ...

  10. 剑指offer(一)——二维数组中的查找

    题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数 ...