牛客多校4: A

简要题意:

给你一些东西,这些东西都有两个属性w和p,可以任意排序ai,要求算出来的

\sum\limits_{i=1}^{m}w_{a_i}\prod\limits_{j=0}^{i-1}p_{a_j}最大

思路:

我们可以想到这题跟洛谷的国王游戏有点像。我们可以先把公式列出后,假设两位的顺序调换了之后,不一样的项。设j=j+1,我们认为i和j两项顺序调换了,那么

Wi*\left ( P0*P1*....Pj \right )+Wj*\left ( P0*P1*P2*...Pj-1 \right )>Wj*\left ( P0*P1*....Pi \right )+Wi*\left ( P0*P1*....Pi-1 \right )

因为后面公式的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]);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值