- 题意:让你计算出交几份论文上去,通过几份时的期望最大,这里的期望为成功概率 * 论文的生产力指数
- 状态表示:dp[i][j]提交前i篇论文,成功j篇的概率
- 集合划分:
- 初始化:dp[0][0] = 1(提交0篇,成功0篇概率肯定为1)
- 特殊情况: dp[i][0] = dp[i-1][0] * (1 - a[i])(前i篇论文提交上去,0篇成功的概率为前i-1篇论文提交后成功0篇的情况概率 * 第i篇失败的概率)
- 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篇失败的概率)
- 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;
}