Gym 101666L(简单dp)

本文介绍了一种使用动态规划解决饮料转换问题的方法,目标是在一系列交易中将初始的pink饮料转换为尽可能多的blue饮料,不超过10升。通过将汇率转化为log2形式并调整DP转移方程,避免了精度损失,最终实现了高效求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

传送门:

题面:

    PDF

题意:

    你最开始有1升的pink饮料,你想要获得blue饮料,现在有n个人,每个人都希望用O饮料换取W饮料,每次的转化率为R。现在你可以跟他们依次的交换饮料,而当你最后得到10升以上的blue饮料后,多余10升的你将抛弃,问你最多能获得多少blue饮料。

题目分析:

    简单的线性dp,令dp[i]为当前编号为i的饮料能够换取的饮料体积,则有转移方程

    但是这个题目中,因为人数最多为1e5,而每次可能使得体积*2,因此如果像上面一样递推,则必定会导致爆double。

    因此我们需要考虑将每次的汇率化为log2的形式,并将转移方程变为:转移,最后变为原值即可。

代码:

#include <bits/stdc++.h>
#define maxn 100005
using namespace std;
struct drink{
    string O,W;
    double rate;
}q[maxn];
map<string,int>mp;
const double INF=1e200;
double dp[maxn];
int main()
{
    int n;
    scanf("%d",&n);
    int cnt=1;
    mp["pink"]=1;
    for(int i=1;i<=n;i++){
        cin>>q[i].O>>q[i].W>>q[i].rate;
        if(!mp.count(q[i].O)) mp[q[i].O]=++cnt;
        if(!mp.count(q[i].W)) mp[q[i].W]=++cnt;
        q[i].rate=log2(q[i].rate);
    }
    for(int i=1;i<=cnt;i++) dp[i]=-INF;
    dp[1]=0;
    for(int i=1;i<=n;i++){
        int idW=mp[q[i].W],idO=mp[q[i].O];
        dp[idO]=max(dp[idO],dp[idW]+q[i].rate);
    }
    if(!mp.count("blue")) puts("0.0000000000");
    else{
        double res=dp[mp["blue"]];
        if(res>log2(10)) puts("10.000000000");
        else printf("%.14f\n",min(10.0,pow(2,res)));
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/Chen-Jr/p/11007202.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值