简要题意:
给你一些东西,这些东西都有两个属性w和p,可以任意排序ai,要求算出来的
最大
思路:
我们可以想到这题跟洛谷的国王游戏有点像。我们可以先把公式列出后,假设两位的顺序调换了之后,不一样的项。设j=j+1,我们认为i和j两项顺序调换了,那么
因为后面公式的i-1是属于调换之前的前面那个j-1是属于调换之前的,我们认为前面的策略能比后面大,我们才能把之前的情况推翻然后做现在的。
那么我们公式最终缩减应该变成Wi*(Pj-1)>Wj*(Pi-1)
那么这样排序完之后我们就可以开始正向dp了
#include<bits/stdc++.h>
using namespace std;
#define int long long
long double f[100005][22];
struct node{
int w;
long double q;
}a[100005];
bool cmp(struct node b,struct node c){
return b.w*(c.q-1)>c.w*(b.q-1);
}
signed main(){
ios::sync_with_stdio(false);
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i].w;
for(int i=1;i<=n;i++){
cin>>a[i].q;
a[i].q=a[i].q*1.0/10000;
}
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++){
for(int j=1;j<=m&&j<=i;j++){
f[i][j]=max(f[i-1][j],f[i-1][j-1]*a[i].q+a[i].w);
}
}
printf("%.12Lf",f[n][m]);
}