2021年度训练联盟热身训练赛第三场 G.Research Productivity Index(概率dp)

  • 题意:让你计算出交几份论文上去,通过几份时的期望最大,这里的期望为成功概率 * 论文的生产力指数
  • 状态表示:dp[i][j]提交前i篇论文,成功j篇的概率
  • 集合划分:
    1. 初始化:dp[0][0] = 1(提交0篇,成功0篇概率肯定为1)
    2. 特殊情况: dp[i][0] = dp[i-1][0] * (1 - a[i])(前i篇论文提交上去,0篇成功的概率为前i-1篇论文提交后成功0篇的情况概率 * 第i篇失败的概率)
    3. dp[i][j] = dp[i-1][j-1] * a[i] + dp[i-1][j] * (1 - a[i])(j <= i) (前i篇提交,成功j篇的概率 = 前i-1篇提交,成功j-1篇的概率 * 第i篇成功的概率 + 前i-1篇提交,成功j篇的概率 * 第i篇失败的概率)
    4. ps:为了期望更大,我们利用贪心的思想,必须先将每篇论文提交成功的概率进行从大到小排序即可。
  • 代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const int N = 105;
double a[N], dp[N][N]; //提交前i篇论文,成功j篇的概率
int n;
double res = 0.0;
bool cmp(double x, double y)
{
    return x > y;
}
int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        double x;
        cin >> x;
        a[i] = x / 100.0;
    }
    sort(a + 1, a + 1 + n, cmp);
    dp[0][0] = 1;
    for(int i = 1; i <= n; i++)
    {
        dp[i][0] = dp[i-1][0] * (1 - a[i]);
        double sum = 0.0;
        for(int j = 1; j <= i; j++)
        {
            dp[i][j] = dp[i-1][j-1] * a[i] + dp[i-1][j] * (1 - a[i]);
            sum += (dp[i][j]) * pow(j, 1.0 * j / (1.0 * i));
        }
        res = max(res, sum);
    }
    printf("%.9lf\n", res);
    return 0;
}

posted @ 2021-03-28 11:21  ~K2MnO4  阅读(74)  评论(0)    收藏  举报