题目大意
n首音乐,第i首被听出来的概率为pi,刚开始听第一首,1s后如果听出来了则放第下一首,否则接着听这一首,第i首在连续听了ti s之后一定会被听出来,问Ts后听出来的歌的期望数量。
分析
我们非常容易想到dp[i][j]表示考虑前i首歌总共用了j秒的期望得分
但是我们发现转移复杂度O(T),总复杂度O(N^3)
于是我们考虑优化
我们想到对于dp[i][j]的一部分答案可以由dp[i][j-1]*(1-p[i])得到
于是转移复杂度优化到了O(1)
细节较多,详见代码
代码
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<cctype> #include<cmath> #include<cstdlib> #include<queue> #include<ctime> #include<vector> #include<set> #include<map> #include<stack> using namespace std; const double eps = 1e-6; double dp[5050][5050],Ans; int t[5050],pp[5050]; int main(){ int n,m,i,j,k,T; scanf("%d%d",&n,&T); for(i=1;i<=n;i++)scanf("%d%d",&pp[i],&t[i]); dp[0][0]=1; for(i=1;i<=n;i++){ double p=(double)pp[i]/100; double x=pow(1-p,t[i]-1); double now=dp[i-1][0]; for(j=1;j<=T;j++){ if(j-t[i]>=0)now-=dp[i-1][j-t[i]]*x; dp[i][j]+=now*p; if(j-t[i]>=0)dp[i][j]+=dp[i-1][j-t[i]]*x; now=now*(1-p)+dp[i-1][j]; Ans+=dp[i][j];//我们不将数首歌期望合起来算,而是每次都累加答案 //但是每次算概率是需要用到之前的期望 } } printf("%0.6lf",Ans); return 0; }
原文地址:https://www.cnblogs.com/yzxverygood/p/10360444.html
时间: 2024-08-28 21:59:40