zoukankan      html  css  js  c++  java
  • [CF28C] Bath Queue

    前言

    经小提示做出来的DP,因为题解没看懂,淦

    题目

    洛谷

    CF

    题目大意:

    ​ 有(n(1≤n≤50))个学生同时洗衣服,有(m(1≤m≤50))个洗衣房,第(i)个洗衣房里有(a_i(1≤a_i≤50))台洗衣机。
    ​ 每个学生会从(m)个洗衣房里随机选择一个,选择同一个洗衣房的学生会按照房间里洗衣机的数量平均排队,求最长队列人数的期望,输出误差不大于(10^{-9})

    ​ 平均排队是指不存在两个队列人数相差大于二。

    讲解

    既然我期望学的差,就不要试图直接DP转移期望了(所以没看懂题解qwq)

    所以我们DP求方案数

    我们令(dp[i][j][k])为前(i)个房间去(j)个人,最长队列恰好(k)的方案数,转移为当前房间进入(l)个人,由(i-1)转移而来

    考虑状态转移方程怎么写

    第一维:(i-1)(i)

    第二维:(j)(j+l)

    第三维:(k)(max(⌈frac{l}{a_i}⌉,k))

    那么(dp[i][j][k])提供的贡献是多少呢?因为人是不一样的,所以我们要从剩下的(n-j)人中选出(l)个人来,所以要乘上(C_{n-j}^{l})

    所以总的状态转移方程即为:

    [dp[i][j+l][max(ceil(l/a[i]),k)]=sum dp[i-1][j][k]*C_{n-j}^{l} ]

    由于多个(sum)会使得转移方程看起来过于冗长且没有什么太大意义,所以我省略掉了

    所以总方案数为:(T=sum_{i=0}^n dp[m][n][i])

    期望与带权平均差不多,而每个(dp[m][n][i])的权值即为(i)

    所以答案为:

    [sum_{i=1}^{n}frac{i*dp[m][n][i]}{T} ]

    什么?你问我为什么(i)(1)开始?难道和从(0)开始有什么区别吗?

    注意:

    1.输入的(n,m)分别指人和房间数,不要搞反了

    2.输出位数不要太少了

    3.建议用( exttt{double})存,万一用( exttt{long long})出事了呢

    代码

    int n,m,a[MAXN];
    double C[MAXN][MAXN],dp[MAXN][MAXN][MAXN],ans,T;
    void pre()
    {
    	C[0][0] = 1;
    	for(int i = 1;i <= 50;++ i)
    	{
    		C[i][0] = 1;
    		for(int j = 1;j <= i;++ j) C[i][j] = C[i-1][j-1] + C[i-1][j];
    	}
    }
    
    int main()
    {
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	pre();
    	n = Read(); m = Read();
    	for(int i = 1;i <= m;++ i) a[i] = Read();
    	dp[0][0][0] = 1;
    	for(int i = 1;i <= m;++ i)
    		for(int j = 0;j <= n;++ j)
    			for(int k = 0;k <= j;++ k)
    				for(int l = 0;l <= n-j;++ l)
    					dp[i][j+l][Max(((l+a[i]-1)/a[i]),k)] += dp[i-1][j][k]*C[n-j][l];
    	for(int i = 0;i <= n;++ i) T += dp[m][n][i];
    	for(int i = 1;i <= n;++ i) ans += i * dp[m][n][i] / T;
    	printf("%.10f",ans);
    	return 0;
    }
    
  • 相关阅读:
    Python入门示例系列07 Python注释
    Python入门示例系列09 Python算术运算
    Python入门示例系列10 字符串(初级)
    SQL循环26个字母插入到一个表中
    UBUNTU LINUX中连接ANDROID 小米真机调试
    Ubuntu下包含2种远程桌面的方式:VINOServer以及VNC Server
    一个合格的程序员应该读过哪些书
    linux下如何查看文件编码格式及转换文件编码
    尽量不要使用文本模式
    S.O.L.I.D.类设计原则
  • 原文地址:https://www.cnblogs.com/PPLPPL/p/13767302.html
Copyright © 2011-2022 走看看