CF908D New Year and Arbitrary Arrangement

简单题。

发现最终状态无限,起始状态有限,考虑逆推(辅以记忆化)

f[x][y][z]x 个 a,ybz 个 ab 的期望 ab 个数。

则考虑能怎样走到哪些状态。

选 a,f[x+1][y][z]

选 b,f[x][y+1][x+y]

发现 b 这一维没啥用,因为前面的 b 对当前构不成影响,删去。

f[x][y]x 个 a,y 个 ab 的期望。

f[x][y]=P(A)f[x+1][z]+P(B)f[x][x+y]

但是可能会有 limx+,即无法知道边界。

考虑当 x+yk,我们只需要算出在选一定次数 a 后选到 b 的期望和即可。

P(B)i=0P(A)i(x+y+i)

代下

i=0pi=11p

i=0pii=p(1p)2

补充下 2 式证明

i=0pii=s

ssp=i=1pii

s(1p)p=i=0pii

s=p(1p)2

#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #include <cstdlib> #include <map> #include <vector> #include <set> #include <cmath> #define int long long using namespace std; int rd() { char ch=getchar(); int sum=0,f=1; while(!isdigit(ch)) { if(ch=='-') f=-1; ch=getchar(); } while(isdigit(ch)) sum=sum*10+ch-'0',ch=getchar(); return f*sum; } const int mod=(int)(1e9+7); int k,a,b,pa,pb,A1,A2; int f[2005][2005]; int fpow(int x,int y) { int res=1; x=(x%mod+mod)%mod; while(y) { if(y&1) res=res*x%mod; x=x*x%mod; y>>=1; } return res; } int dfs(int x,int y) { if(x+y>=k) return pb*((x*A1%mod+y*A1%mod+A2)%mod)%mod; if(f[x][y]) return f[x][y]; return f[x][y]=(pa*dfs(x+1,y)%mod+pb*dfs(x,x+y)%mod)%mod; } signed main() { k=rd(); a=rd(); b=rd(); pa=a*fpow(a+b,mod-2)%mod; pb=b*fpow(a+b,mod-2)%mod; A1=fpow(1-pa,mod-2)%mod; A2=pa*fpow(1-pa,mod-2)%mod*fpow(1-pa,mod-2)%mod; printf("%lld",(dfs(1,0)%mod+mod)%mod); return 0; }

__EOF__

本文作者F x o r G
本文链接https://www.cnblogs.com/xugangfan/p/15872342.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   FxorG  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示