CF601 C 题解

C:

题意:m个人参加n场比赛,每个人最终排名为每次比赛名次相加排序,已知主角每场比赛的名次,求其最终排名的期望值。(n<=100, m<=1000)

Solution:

好家伙完全没有思路,看题解发现原来期望dp还能这么玩儿。

f[i][j] 表示前 i 场比赛名次和为 j 的人数期望有多少个。

我们发现这个状态是可以转移的,而且转移方程很好写:

f[i][j]=k=1mf[i1][jk]   (ka[i])m1

这是什么呢,就是说如果一些人想要在 i 场比赛后名次和为 j ,他们可以是前 i-1 场和为 j-k,第 i 场名次为 k。f[i][j] 这个状态的值,就是前一场的那些期望人数乘上可以转移到此状态的概率,求和。

由于 k 不能和 a[i] 相等,因此对于所有人,第 i 场名次为 k 的概率都是 1m1

最终答案就是严格小于主角名次和的人数的期望值 f[n][0]f[n][sum1] 再加一。

整个dp过程用前缀和优化,复杂度O(n^2m)。

typedef long double ld; int T; int n,m; int ans,a[N]; ld f[2][111111]; int da,he; int main() { n = read(); m = read(); da = n*m; if(m==1) {cout<<"1.0000000000000000"<<endl; return 0;} for(int i=1;i<=n;i++) a[i] = read(), he += a[i]; for(int i=0;i<=da;i++) f[0][i] = m-1; for(int i=1;i<=n;i++) { int cl = i&1; f[cl][0] = 0.0; for(int j=1;j<=da;j++) { f[cl][j] = f[cl][j-1] + (f[cl^1][j-1] - ((j-m-1>=0)?f[cl^1][j-m-1]:0) - ((j-a[i]>=0)?f[cl^1][j-a[i]]:0) + ((j-a[i]-1>=0)?f[cl^1][j-a[i]-1]:0)) / (ld)(m-1.0); } } printf("%.12Lf",f[n&1][he-1]+1.0); return 0; }

__EOF__

本文作者枫叶晴
本文链接https://www.cnblogs.com/maple276/p/18026462.html
关于博主:菜菜菜
版权声明:呃呃呃
声援博主:呐呐呐
posted @   maple276  阅读(13)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示