JZOJ5244. 【NOIP2017模拟8.8A组】Daydreamin

Description

  worldwideD最近有午睡的习惯~
   某日中午,他做了一个梦:梦见有一个怪人,她去一个岛上住N+1天(编号为0到N)。这是在大洋中的岛,每天要么是晴天,要么刮台风。
   她到达岛的第0天是晴天(这样她才能上岸)。然后对于第i天,假如是晴天,那么有P(0<P≤1)的几率会变天:接下来连续M天都刮台风,然后第i+M+1天必然会转晴。
   天气对她的心情会有影响,用一个值来描述她每一天的心情:如果第i天是晴天,那么这个值为A;如果是雨天,那么岛上有D(0<D≤1)的几率会发生杀人案件,如果没发生杀人案件,这个值为B,否则为C。
   worldwideD醒来了,他想知道编号1到N天的心情值之和的期望值。

Data Constraint

30%:N≤20
50%:N≤2,000
100%:1≤M≤N≤1,000,000 1≤A,B,C≤1,000 1≤P,D<998244353

分析

很显然,我们应该先求概率。
fi 表示第i天是晴天的概率,
那么, 1fi 就表示第i天是雨天的概率。

首先,可以从 fi1 转移过来,
第i-1天的概率乘上这天不变天的概率,即 fi+=fi1(1p)
也可以从i-m-1天转移过来,
第i-m-1天变天了,之后的连续m天都是雨天,那么第i天就必定是晴天。
fi+=fim1p

考虑每天的期望,
晴天的期望: fiA
雨天的期望: (1fi)(dc+(1d)b)
最后求和就可以了。

code

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string.h>
#include <cmath>
#include <math.h>
#define N 1000003
#define mo 998244353
#define ll long long
using namespace std;
int n,m;
ll p,d,a,b,c,f[N],s,ans;
ll ksm(ll x,int y)
{
    ll s=1;
    while(y)
    {
        if(y%2)s=s*x%mo;
        x=x*x%mo;
        y>>=1;
    }
    return s;
}
int main()
{
    freopen("daydream.in","r",stdin);
    freopen("daydream.out","w",stdout);
    scanf("%d%d%lld%lld%lld%lld%lld",&n,&m,&p,&d,&a,&b,&c);
    f[0]=1;
    s=(1+mo-d)*b%mo+c*d%mo;
    s%=mo;
    for(int i=1;i<=n;i++)
    {
        f[i]=f[i-1]*(mo+1-p)%mo;
        if(i>=m)
        {
            f[i]=(f[i]+p*f[i-m-1])%mo;
        }
        ans=(ans+f[i]*a%mo+(mo+1-f[i])*s%mo)%mo;
    }
    printf("%lld",ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值