• 498B Name That Tune


    传送门

    题目大意

    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; }
  • 相关阅读:
    Redis流程初始认知
    浅谈windows和linux进程和线程的区别
    linux下的信号量PV操作进阶之路
    linux下线程以及pthread库
    分清问题的主次
    linux下主线程return 0和pthread_exit(NULL)的区别
    进程和线程的区别
    注意搜索的陷阱
    模拟主线程等待子线程的过程
    【伯乐在线】编程面试的10大算法概念汇总
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/10360444.html
Copyright © 2020-2023  润新知