题意:
有n首长度为l[i]的歌,每首歌Manao有p[i]的概率喜欢。在听歌时,若Manao听到了一首不喜欢的歌他会再听完这首歌后返回去听之前所有喜欢的歌。问Manao听完这n首歌的时间期望最大是多少。听歌的顺序由我们来安排。
思路:
对于两首歌a、b来说,我们有先听a再听b和先听b再听a的顺序选择,那么我们选择的依据是选一个对答案贡献最大的顺序,两种顺序对答案的贡献如何求呢?很简单。只有喜欢第一首歌并且不喜欢第二首歌我们才会在听完第二首歌后返回去听第一首歌,这时候他们的期望就为:la*pa*(1-pb)和lb*pb*(1-pa)。然后以这个为依据sort一遍就可以排好顺序了。然后如何求总的期望呢?假设现在听到第k首歌,那么它对答案的贡献为:(l1*p1+l2*p2+...+l[k-1]*p[k-1])*(1-p[k])即第k首歌不喜欢时才会返回去听之前的歌,才会对答案有贡献。
#include<cstdio>
#include<algorithm>
#define eps 1e-9
using namespace std;
const int MAX=50005;
struct Node{
double l,p;
}a[MAX];
bool cmp(Node a,Node b){
return a.l*a.p*(1-b.p)-b.l*b.p*(1-a.p)>eps;
}
int main(){
int n;
scanf("%d",&n);
double ans=0;
for(int i=0;i<n;i++){
scanf("%lf%lf",&a[i].l,&a[i].p);
a[i].p/=100.0;
ans+=a[i].l;
}
sort(a,a+n,cmp);
double tmp=0;
for(int i=0;i<n;i++){
ans+=tmp*(1-a[i].p);
tmp+=a[i].l*a[i].p;
}
printf("%.9lf\n",ans);
return 0;
}