CodeForces-28C-Bath Queue-概率DP[ ICPC大连热身D]

题目地址 http://codeforces.com/problemset/problem/28/C

代码+注释

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
//前i个澡堂,一共j个人,最长队伍为k的概率
//dp[i][j][k]
double dp[55][55][100];
int a[55];
double C[55][55];
void init() {
    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()
{
    int m,n;
    scanf("%d%d",&n,&m);
    init();//求组合数
    memset(dp,0,sizeof(dp));
    for ( int i = 1; i <= m ; i++ )  scanf("%d",&a[i]);
    dp[0][0][0] = 1; // dp初始化
    for (int i = 1 ; i <= m; i++)
    {
       for (int j = 0; j <= n ; j++)
       {
            for ( int k = 0; k <= n; k++)
            {
                //枚举[i][j][k]
                //计算dp[i][j][k]
                int top = min(k*a[i],j);
                //只有当前澡堂最长队伍小于等于k时。才能转移
                for (int c = 0 ; c <= top ; c++) //i澡堂中人数
                {
                    if (k*a[i]-a[i]+1 > c) // 如果当前 澡堂最大值不是k 只能从dp[i-1][j-c][k]转移
                        dp[i][j][k] += dp[i-1][j-c][k] * pow(i-1,j-c)  / pow(i,j) * C[j][c];
                    else // 如果当前为k,可以从 dp[i-1][j-c][<=K]转移
                         for (int tt = 0; tt<=k ;tt++)
                            dp[i][j][k] += dp[i-1][j-c][tt] * pow(i-1,j-c)  / pow(i,j)* C[j][c];
                }
            }
       }
    }
    double  ans = 0;
    for (int i = 1 ; i <= n; i++)
    {
       ans += dp[m][n][i] * i;
    }
    printf("%.10f\n",ans);
    return 0;
}
时间: 2024-10-10 01:56:13

CodeForces-28C-Bath Queue-概率DP[ ICPC大连热身D]的相关文章

codeforces 482c 状压+概率DP

题意:给出N个不同的串,长度一样,别人随机选一个串,你要询问他那个串某一个位置是什么字符直到能确定那个串才能停止,问询问次数的期望. 题解:50个串20个位置容易想到状压,把字符串长度状压先考虑能否在某一个状态确定哪些字符串能确定哪些不能确定,需要2^m*m次,然后时间上不能再乘以n不然会爆,想想只要我知道到达某一个猜位置状态的概率dp[i],再知道相对应有哪些字符串可以确定和不可以确定,用f[i]来表示,那么对于不能确定的字符串相当于就要再猜一步,那么加上这个状态的概率就行了,不会再需要乘以n

codeforces Name That Tune (概率dp)

题意: D - Name That Tune Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Practice CodeForces 499D Appoint description:  System Crawler  (2015-01-05) Description It turns out that you are a great fan of rock b

codeforces 1156F Card Bag 概率dp

Card Bag 状态只会从a小转移到a大,随便dp就好了. #include<bits/stdc++.h> using namespace std; const int N = 5000 + 7; const int mod = 998244353; int n, a[N], sum[N], dp[N][N], sum_dp[N]; int inv[N]; int main() { inv[1] = 1; for(int i = 2; i < N; i++) { inv[i] = 1L

Codeforces 28C [概率DP]

/* 大连热身D题 题意: 有n个人,m个浴室每个浴室有ai个喷头,每个人等概率得选择一个浴室. 每个浴室的人都在喷头前边排队,而且每个浴室内保证大家都尽可能均匀得在喷头后边排队. 求所有浴室中最长队伍的期望. 思路: 概率dp dp[i][j][k]代表前i个浴室有j个人最长队伍是k的概率. 枚举第i个浴室的人数.然后转移的时候其实是一个二项分布. */ #include<bits/stdc++.h> using namespace std; int jilu[55]; double dp[

Codeforces 518D Ilya and Escalator (概率dp)

Ilya and Escalator time limit per test: 2 seconds memory limit per test: 256 megabytes Ilya got tired of sports programming, left university and got a job in the subway. He was given the task to determine the escalator load factor. Let's assume that

codeforces 235B Let&#39;s Play Osu! 概率dp

题意:给定n表示有n个格子,下面每个格子为O的概率是多少.对于一段连续 x 个O的价值就是 x^2 ;求获得的价值的期望是多少. 思路:n^2=n×(n-1)+n,设ai为第i段连续O的长度,∑ai^2 = ∑[ ai+ ai*(ai-1) ] = ∑ ai*(ai-1) + ∑ai = ∑ C(ai, 2)*2 + ∑ai,那么问题可以转 化为求长度大于1的连续段数*2+O的个数的总期望. ∑ai我们可以理解为O的总个数,所以它的期望为∑pi: C(ai, 2)*2我们可以认 为是连续ai个O

codeforces 148D 【概率dp】

题目链接: codeforces 148D Bag of mice 题意:一个包里面有w只白老鼠和b只黑老鼠,公主与龙依次从包中拿老鼠,每次取一只,当龙拿时还会从包中溜走一只,先拿到老鼠的获胜,当背包中没老鼠时且之前没人拿到白老鼠则龙获胜,问公主获胜的概率是多少. 题解: 设dp[i][j]为背包中有i只白老鼠j只黑老鼠时公主获胜的概率 则公主获胜的情况分成三种: 1.直接拿到白老鼠 p1=i/(i+j) 2.公主拿到黑老鼠,龙拿到黑老鼠,逃跑一只黑老鼠 p2=(j/(i+j)) ((j-1)/

Codeforces Div.301D Bad Luck Island(概率dp+记忆化搜索)

一道概率dp问题. 题目链接:http://codeforces.com/contest/540/problem/D 题目大意:一个岛上有r个石头,s个剪子,p个布,他们之间随机挑出两个相遇,如果不是相同物种,就会有一个消失,分别求出最后这座岛上只剩下一个物种的概率. 我们用dp[i][j][k]来存储i个石头,j个剪刀,k个布时,某物种的存活概率,共dp三次,算出三个物种分别的概率. 首先,我们需要把对应想求的物种概率初始化,这里以石头为例,那么对于i从1到r,不难理解dp[i][0][0]=

CodeForces 540D Bad Luck Island 概率dp

CodeForces 540D 应该是简单概率dp,由于写得少显得十分蠢萌 求期望逆推,求概率正推,大概是这么个意思,贴一发留恋 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define db double const int maxn=108; db dp[maxn][maxn][maxn]; int main() { int i,j,n,m,k,p; whi