题目写的比较难懂,题目大意:给你一个n,m代表有n首歌,在m秒内进行猜歌。让你求出m秒过后你能猜出来的歌曲的数量的期望。接下来n行,每行有两个数字第一个pi代表在歌曲结束前你猜出来的概率,第二个ti代表这首歌最多播放ti秒,在t秒之后你百分比之百能猜出来歌曲。最后输出m秒之后猜出来的歌曲的期望。
我们设dp[i][j]表示枚举到第i首歌,所用时间恰好为j的期望。
dp[i][j] 可以由状态dp[i-1][j-ti],dp[i-1][j-ti+1],......,dp[i-1][j-1]转移过来。
dp[i][j] = dp[i-1][j-ti]*(1-pi)^(ti-1)+dp[i-1][j-ti+1]*(1-pi)^(ti-2)*p+dp[i-1][j-ti+2]*(1-pi)^(ti-3)*p+......+dp[i-1][j-1]*p
需要注意的是dp[i][j-ti]此时第i首歌曲一定会猜中。所以dp[i][j] += dp[i-1][j-ti]*pow((1-pi), ti);
还有就是要减去之前无用的状态,dp[i-1][j-ti-1]的状态是推不到dp[i][j]的所以要减去。
设ans=dp[i-1][j-ti+1]*(1-pi)^(ti-2)+dp[i-1][j-ti+2]*(1-pi)^(ti-3)+......+dp[i-1][j-1],这样从j推向j+1时只要ans=ans*(1-pi)+dp[i-1][j]
#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <ctime>
#include <map>
#include <set>
#define eps 1e-9
///#define M 1000100
///#define LL __int64
#define LL long long
///#define INF 0x7ffffff
#define INF 0x3f3f3f3f
#define PI 3.1415926535898
#define zero(x) ((fabs(x)<eps)?0:x)
#define mod 1000000007
#define Read() freopen("autocomplete.in","r",stdin)
#define Write() freopen("autocomplete.out","w",stdout)
#define Cin() ios::sync_with_stdio(false)
using namespace std;
inline int read()
{
char ch;
bool flag = false;
int a = 0;
while(!((((ch = getchar()) >= '0') && (ch <= '9')) || (ch == '-')));
if(ch != '-')
{
a *= 10;
a += ch - '0';
}
else
{
flag = true;
}
while(((ch = getchar()) >= '0') && (ch <= '9'))
{
a *= 10;
a += ch - '0';
}
if(flag)
{
a = -a;
}
return a;
}
void write(int a)
{
if(a < 0)
{
putchar('-');
a = -a;
}
if(a >= 10)
{
write(a / 10);
}
putchar(a % 10 + '0');
}
const int maxn = 5050;
struct node
{
double p;
int ti;
}f[maxn];
double dp[maxn][maxn];
int main()
{
int n, m;
while(cin >>n>>m)
{
for(int i = 1; i <= n; i++)
{
scanf("%lf %d", &f[i].p, &f[i].ti);
f[i].p /= 100.0;
}
for(int i = 0; i <= m; i++) dp[0][i] = 0;
dp[0][0] = 1;
double sum = 0.0;
for(int i = 1; i <= n; i++)
{
double ans = 0;
double q = pow(1-f[i].p, 1.0*f[i].ti);
for(int j = 0; j <= m; j++)
{
if(j-1 >= 0) ans += dp[i-1][j-1];
if((j-f[i].ti-1) >= 0) ans -= dp[i-1][j-f[i].ti-1]*q;
dp[i][j] = ans*f[i].p;
if(j-f[i].ti >= 0) dp[i][j] += dp[i-1][j-f[i].ti]*q;
ans *= (1.0-f[i].p);
sum += dp[i][j];
}
}
printf("%.10lf\n", sum);
}
return 0;
}