https://open.kattis.com/problems/researchproductivityindex
这道题是考场上没写出来的一道题,今年看看感觉简单到不像话,当时自己对于dp没有什么概念,所以导致考场只能空流泪
首先问期望,肯定就要确定概率。看到这个
就知道肯定一块求是不太好写的,先求上面,上面求发表的期望,那么对于期望我们有e(x) = Σxipi
这里p知道了但是xi不知道,那么我们根据题目描述我们有一个分子一个分母,分子是发表的次数,分母是论文数,首先对于任何j篇论文发表了 i 篇来讲,都无外乎两种情况,一个是上一篇就发表了这么多,这一篇虽然多了一篇论文但没有对论文发表数产生贡献,那么这种情况概率 1- p,第二种情况就是这种发表了,这种情况概率是p
那么状态转移方程显然就有
dp[i][j] = (a[i]) * dp[i - 1][j - 1] + (1 - a[i]) * dp[i - 1][j];//新增没发表和发表
我们要求最大,所以要先从几率大的开始发表,sort一遍(我脑残还降序排了,赶紧reverse),然后不发表的次数initialize一下,求出来上面那一拨东西之后就再转化成发表成功次数,pow函数求解,枚举,看哪个大就可了,真的超级简单一个dp,md去年的没做出来真是耻辱啊啊啊啊
#include <bits/stdc++.h>
using namespace std;
#define limit (100 + 5)//防止溢出
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f
#define lowbit(i) i&(-i)//一步两步
#define EPS 1e-6
#define FASTIO ios::sync_with_stdio(false);cin.tie(0);
#define ff(a) printf("%d\n",a );
#define pi(a,b) pair<a,b>
#define rep(i, a, b) for(ll i = a; i <= b ; ++i)
#define per(i, a, b) for(ll i = b ; i >= a ; --i)
#define MOD 998244353
#define traverse(u) for(int i = head[u]; ~i ; i = edge[i].next)
#define FOPEN freopen("C:\\Users\\tiany\\CLionProjects\\acm_01\\data.txt", "rt", stdin)
#define FOUT freopen("C:\\Users\\tiany\\CLionProjects\\acm_01\\dabiao.txt", "wt", stdout)
#define debug(x) cout<<x<<endl
typedef long long ll;
typedef unsigned long long ull;
inline ll read(){
ll sign = 1, x = 0;char s = getchar();
while(s > '9' || s < '0' ){if(s == '-')sign = -1;s = getchar();}
while(s >= '0' && s <= '9'){x = (x << 3) + (x << 1) + s - '0';s = getchar();}
return x * sign;
}//快读
void write(ll x){
if(x < 0) putchar('-'),x = -x;
if(x / 10) write(x / 10);
putchar(x % 10 + '0');
}
int n;
double a[limit];
double dp[limit][limit];//代表在i篇论文发表了j篇,
int main() {
#ifdef LOCAL
FOPEN;
#endif
n = read(); rep(i ,1,n){
a[i] = (1.0 * read()) / 100;
} sort(a + 1, a + 1 + n);
reverse(a + 1, a + 1 + n);
dp[0][0] = 1;
dp[1][1] = a[1];
dp[1][0] = 1 - a[1];
rep(i ,2,n)dp[i][0] = dp[i - 1][0] * (1 - a[i]), dp[i][i] = dp[i - 1][ i - 1] * a[i];
rep(i ,1,n){
rep(j, 1,i){
dp[i][j] = (a[i]) * dp[i - 1][j - 1] + (1 - a[i]) * dp[i - 1][j];//新增没发表和发表
}
}
double ans = 0;
rep(i ,1,n){
double tmp = 0;
rep(j, 1,i){
tmp += dp[i][j] * pow(j,1.0 * j / (1.0 * i));
}
ans = max(tmp, ans);
}
cout<<fixed<<setprecision(6)<<ans<<endl;
return 0;
}