G - Research Productivity Index ( 数学期望 )
题意:小明手里有n份代码,每一份代码都有一个ac成功率。f值等于,其中a为ac的数量,b为总提交数,比如交了5份4份ac, f =
≈3.031433 , 最后问交几份怎么交期望值最大。
Sample Input :
5 30 50 70 60 90
Sample Output
2.220889579
分析:自己还是对于期望的理解不够深刻,期望=当前情况的概率 * f值, 其中f的值代数的时候肯定都是整数的!!比赛时想错了直接把算出来的概率值往f里带,怎么也算不出来。
思路:dp[ i ] [ j ] 表示取前 i 个交上, 其中有j个ac的概率。状态迁移方程是dp[ i ] [ j ] = dp[ i-1 ] [ j ] * ( 1 - a[i] ) + dp[ i-1 ] [ j-1 ] * a[ i ];
优先取ac概率大的,for循环1~n取最大值。
代码:
#include <bits/stdc++.h>
using namespace std;
int n;
double tot,now;
double a[105];
double dp[102][102]; // 交前i个,j个ac.
int main()
{
cin >> n;
for ( int i=1; i<=n; i++ ) {
int x;
scanf("%d",&x);
a[i] = x*0.01;
}
sort(a+1,a+n+1,greater<double>());
dp[0][0] = 1;
double ans = 0;
for ( int i=1; i<=n; i++ ) {
dp[i][0] = dp[i-1][0]*(1-a[i]);
for ( int j=1; j<=i; j++ ) {
dp[i][j] = dp[i-1][j]*(1-a[i]) + dp[i-1][j-1]*a[i];
}
double now = 0;
for ( int j=1; j<=i; j++ ) {
now += dp[i][j]*pow(j,1.0*j/i);
}
ans = max(ans,now);
}
printf("%.9f\n",ans);
return 0;
}