AGC056E-Cheese【dp】

0|1前言

奶酪可能会长腿,但绝对不会变质
_ _,_ _ _ _ _ _ _


1|0正题

题目链接:https://atcoder.jp/contests/agc056/tasks/agc056_e


1|1题目大意

有一个长度为n的环,第i+0.5(0i<n)位置上各有一只老鼠。

然后进行以下操作n1次:
i个位置有ai%的概率被选择(选择一个),然后在这个位置上放一个奶酪,这个奶酪会顺时针跑,跑到一个老鼠的位置时有50%的概率被吃掉,老鼠如果吃过奶酪就会离开。

求每只老鼠被留到最后的概率。

1n50,i=0n1ai=100


1|2解题思路

考虑第n只老鼠留到最后的概率,因为无论是哪只奶酪吃什么老鼠都是一样的,所以我们可以考虑开始时就将所有的奶酪放下来,然后让它们一起绕着环走。

同样的,奶酪的移动顺序也是无关紧要的,所以我们可以考虑让所有的奶酪先绕道第n只老鼠的面前然后一起统计。

那么先考虑dp,设fi,j,k表示现在已经放下的奶酪都已经走到了位置i处,然后已经放下了j个奶酪,已经有k个被老鼠吃了。

那么每次的转移分成两部分,第一部分是放奶酪,枚举这个位置放置了x个奶酪,需要注意的是除了概率以外因为这个方案是涉及可重排列的,所以还需要乘上一个1x!

第二部分是吃奶酪,因为每只奶酪只会吃一个老鼠,所以统计没有这些奶酪都没有被吃的概率,很方便转移。

那么假设目前有k个奶酪走到了第n只老鼠前,那么说明前面还剩下k1只老鼠没有被吃,那么考虑这种情况下第n只老鼠被留到最后的概率。

考虑一个神必的证明方法,我们考虑绕一圈绕到第i只老鼠处还剩下x个奶酪,然后考虑ii+1之间被留到最后的概率:

  • 如果ii+1都吃到了,我们显然得不出两个的概率关系。
  • 如果ii+1都没被吃到,我们也得不出来,考虑下一轮。
  • 如果i吃了并且i+1没吃,概率是(112x)12x1
  • 如果i没吃并且i+1吃了,概率是12x(112x)

那么记pi表示i留到最后的概率,就有pi:pi+1=12x(112x):(112x)12x1=1:2
然后又因为i=1k1pi=1,所以有pi=2i12k1,那么我们要求的就是p1=12k1

然后这样是求第n只老鼠的,改一下其他的ai就好了。

时间复杂度:O(n5)


1|3code

#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const ll N=55,P=998244353; ll n,fac[N],inv[N],pw[N],pr[N]; ll a[N],f[N][N][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; } signed main() { scanf("%lld",&n); fac[0]=inv[0]=inv[1]=pw[0]=pr[0]=1; for(ll i=2;i<N;i++)inv[i]=P-inv[P%i]*(P/i)%P; for(ll i=1;i<N;i++)fac[i]=fac[i-1]*i%P,inv[i]=inv[i-1]*inv[i]%P; for(ll i=1;i<N;i++)pw[i]=pw[i-1]*inv[2]%P,pr[i]=pr[i-1]*2ll%P; for(ll i=0;i<n;i++)scanf("%lld",&a[i]),a[i]=a[i]*power(100,P-2)%P; ll sum=0; for(ll s=0;s<n;s++){ //f[i][j][k]表示到s+i,j个奶酪,被吃了k个 memset(f,0,sizeof(f));f[0][0][0]=1; for(ll x=1;x<=n;x++){ for(ll i=0;i<n;i++) for(ll j=0;j<=i;j++) for(ll k=0,r=1;k<=i-j;k++,r=r*a[(s+x)%n]%P) (f[x][i][j]+=f[x-1][i-k][j]*r%P*inv[k]%P)%=P; if(x==n)continue; for(ll i=0;i<n;i++) for(ll j=i-1;j>=0;j--){ (f[x][i][j+1]+=f[x][i][j]*(1-pw[i-j])%P)%=P; (f[x][i][j]=f[x][i][j]*pw[i-j]%P)%=P; } } ll ans=0; for(ll i=1;i<=n;i++) (ans+=f[n][n-1][n-i]*fac[n-1]%P*power(pr[i]-1,P-2)%P)%=P; printf("%lld ",(ans+P)%P);sum=(sum+ans)%P; } return 0; }

__EOF__

本文作者QuantAsk
本文链接https://www.cnblogs.com/QuantAsk/p/16087753.html
关于博主:退役OIer,GD划水选手
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   QuantAsk  阅读(33)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
历史上的今天:
2021-04-01 2020牛客NOIP赛前集训营-提高组(第三场)C-牛半仙的妹子Tree【虚树,最短路】
2021-04-01 牛客练习赛71E-神奇的迷宫【点分治,NTT】
2021-04-01 NOI.AC#2007-light【根号分治】
2021-04-01 CF1370F2-The Hidden Pair(Hard Version)【交互题,二分】
2021-04-01 P3335-[ZJOI2013]蚂蚁寻路【dp】
点击右上角即可分享
微信分享提示