codeforces 498B 概率DP

codeforces 498B


题意:

n 在一场猜歌游戏中,n首歌按顺序播放,猜中一首歌后直接播放下一首。
i t i p i t i 100 % t i 第i首歌在t_i秒内的猜中概率为p_i,在t_i秒后的猜中概率为100\%,t_i为最大播放时长。
T 问T秒内猜中歌曲数量的期望。


题解:

d p [ i ] [ j ] i j dp[i][j]表示第i首歌在第j秒被猜中的概率。

  • d p [ i ] [ j ] = d p [ i ] [ j t [ i ] ] ( 1 p [ i [ ) t [ i ] + k = 1 t [ i ] 1 d p [ i 1 ] [ j k ] p [ i ] ( 1 p [ i ] ) k 1 dp[i][j]=dp[i][j-t[i]]*(1-p[i[)^{t[i]}+\displaystyle\sum_{k=1}^{t[i]-1} dp[i-1][j-k]*p[i]*(1-p[i])^{k-1}
  • j = m k < t [ i ] d p [ i 1 ] [ j ] + = d p [ i 1 ] [ j k ] ( 1 p [ i ] ) k j=m且k<t[i]时,dp[i-1][j]+=dp[i-1][j-k]*(1-p[i])^k
  • a n s = i = 1 n 1 d p [ i ] [ m ] i + i = 1 m d p [ n ] [ i ] n ans=\displaystyle\sum_{i=1}^{n-1}dp[i][m]*i+\displaystyle\sum_{i=1}^{m}dp[n][i]*n

#include <bits\stdc++.h>
using namespace std;
const int N = 5001;
int t[N];
double p[N];
double dp[N][N];

int main() {
    int n, T;
    cin >> n >> T;
    for(int i = 1 ; i <= n ; i++){
        cin >> p[i] >> t[i];
        p[i] /= 100;
    }
    dp[0][0] = 1;
    double ans = 0;
    for(int i = 1 ; i <= n ; i++){
        double sum = 0, item, power = pow(1-p[i], t[i]-1);
        for(int j = 1 ; j <= T ; j++){
            sum = sum*(1-p[i])+dp[i-1][j-1]*p[i];
            if(j >= t[i]){
                sum = sum-dp[i-1][j-t[i]]*p[i]*power;
                item = sum+dp[i-1][j-t[i]]*power;
            }
            else{
                item = sum;
            }
            dp[i][j] += item;
            ans += dp[i][j];
        }
    }
    cout << setiosflags(ios::fixed) << setprecision(9) << ans << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/CSDN_PatrickStar/article/details/89819934