分手是住院「期望dp」

Posted znsbc-13

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分手是住院「期望dp」相关的知识,希望对你有一定的参考价值。

这个题如果各位大神做的话肯定是"当时秒切"

像我这种据若就算了吧

题解

首先考虑没有随机的情况

从大到小枚举看是最优的,

感性理解,你大的一定要选,你如果小的选了之后你大的可能让当前小的翻转,你当前选的可能是无意义的,

(说人话就是你选大的可能会对小的造成影响,你选小的一定不会对大的造成影响)

设f[i]表示当你还剩i个开关要按时期望步数

那么题目中说最后k步选最优策略就没用了,f[i]一定会选择最优即一定按需要按的必须选的灯f[i]=1

那么考虑随机,

贡献分两部分,1.按你需要按的$\fracin$2.按不需按的是$\fracn-in*(f[i+1]+f[i]+1)$

解释一下,你选到不该选的,你要用$1$步到$f[i+1]$状态,然后你要用$f[i+1]$步翻转回来,,回到当前状态之后你还要花$f[i]$步达到当前选到正确灯状态(这个式子让我们想起了tree这个题,很像不是吗)

关于求必选集合,用$vector$维护约数就行了

代码

技术图片
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define A 1010101
#define mod 100003
ll f[A],a[A],inv[A];
ll cnt=0,n,k;
vector <ll> vec[A];
int main()
    scanf("%lld%lld",&n,&k);
    f[n]=1;inv[1]=1;
    for(ll i=2;i<=n;i++) 
        inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
    for(ll i=1,v;i<=n;i++)
        scanf("%lld",&a[i]);
    for(ll i=1;i<=n;i++)
        for(ll j=i;j<=n;j+=i)
            vec[j].push_back(i);
    for(ll i=n;i>=1;i--)
        if(!a[i]) continue ;
        for(ll j=0;j<vec[i].size();j++)
            a[vec[i][j]]^=1;
        cnt++;
    
    for(ll i=n-1;i>k;i--)
        f[i]=(n+(n-i)*f[i+1]%mod)*inv[i]%mod;
    for(ll i=k;i>=1;i--)
        f[i]=1;
    ll ans=0;
    for(ll i=1;i<=cnt;i++)
        (ans+=f[i])%=mod;
    for(ll i=1;i<=n;i++)
        ans=ans*i%mod;
    printf("%lld\n",ans);
View Code

 

以上是关于分手是住院「期望dp」的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ4872: [Shoi2017]分手是祝愿 期望DP

[BZOJ4872][六省联考2017]分手是祝愿(期望DP)

[六省联考2017]分手是祝愿 题解(期望dp)

[HEOI2017]分手是祝愿 期望概率dp 差分

bzoj4872[Shoi2017]分手是祝愿 数论+期望dp

LOJ #2145. 「SHOI2017」分手是祝愿