• 【NOIP模拟】小迟的锦标赛


    题面

    小迟最近去参加了一个锦标赛,这个锦标赛总共有 n 轮比赛,最终成绩由这 n 轮比赛中赢的轮数决定。由于小迟每轮比赛的胜利概率,则取决于他在该轮比赛之前的战绩。也就是说,如果小迟在第 i 轮比赛选择积极应战,并且前 i-1 轮比赛中取得了 j 胜的话,那么第 i 轮比赛的胜率概率为p[i][j],这里我们保证了一点就是对于同一个 i,p[i][j] 关于 j 的上升保持调不上升(也就是说 p[i][j]>p[i][j+1])。小迟观察到这个规则之后,想到了一个可能可以使他最终成绩更优的方法,就是在某些轮比赛采取第2种策略,故意求败,也就是以 100% 的概率输掉该轮比赛,从而使自己在后面能够遇到更容易对付的对手。
    小迟现在已经看到了整个 p 数组,小迟希望你能告诉他一个最优的策略,使得他能最大化他的期望赢的轮数。

    分析

    其实放水只是个烟雾弹,小数据其实是在疯狂暗示你,放水一定不会更优。

    拿2轮比赛举例子 假设p0是赢第1轮的概率,p1是赢第1轮后赢第2轮的概率,p2是没赢第一轮却赢第2轮的概率

    不放水的期望:p0*p1*2+p0*(1-p1)+(1-p0)*p2=p0*(1+p1-p2)+p2

    放第一轮的水的期望:p2

    放第二轮的水的期望:p0

    作差比较,一式减二式得 p0*(1+p1-p2)显然>=0  一式减三式得 p0*(p1-p2)+p2=p0*p1+p2*(1-p0) 显然>=0

    所以无论怎么放水,都不会比不放水优秀

    因此我们只需要做一个dp就好了,期望和概率都可以,这里是正着做就是概率dp

    前i+1场中赢j+1场的概率+=前i+1场中赢j场的概率*本场赢的概率

    前i+1场中赢j场的概率+=前i+1场中赢j场的概率*本场输的概率

    最后算一下期望就好了

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define N 1010
    #define db double
    int n;
    db ans,f[N][N],p[N][N];
    
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            for(int j=0;j<i;j++)
                scanf("%lf",&p[i][j]);
        f[0][0]=1;
        for(int i=0;i<n;i++)
            for(int j=0;j<=i;j++)
            {
                f[i+1][j+1]+=f[i][j]*p[i+1][j];
                f[i+1][j]+=f[i][j]*(1-p[i+1][j]);
            }    
        for(int i=0;i<=n;i++)ans+=f[n][i]*i; 
        printf("%.2lf",ans);
        return 0;
    }
    
         
  • 相关阅读:
    让我用69406条评论告诉你“反贪风暴”好不好看!!!
    【大数据】爬取全部的校园新闻
    【大数据】获取一篇新闻的全部信息
    【大数据】理解爬虫原理
    中文统计
    [大数据]统计词频
    数据库表设计以及表字段命名
    设计模式的理论理解
    文件上传之oss服务器上传文件简笔
    QueryWrapper/UpdateWrapper认识
  • 原文地址:https://www.cnblogs.com/NSD-email0820/p/9923636.html
Copyright © 2020-2023  润新知