W
e
l
c
o
m
e
: )

题解:CF913C Party Lemonade

分析

因为容量为 \(2^{i-1}\),所以对于任意的 \(i<j\),第 \(j\) 种瓶子一定可以通过选择 \(2^{j-i}\)\(i\) 种瓶子来实现。

定义一个瓶子的性价比为 \(\dfrac{\textrm{容量}}{\textrm{价格}}\),即 \(\dfrac{2^{i-1}}{c_i}\)

我们可以按照每个瓶子的性价比从高到低排序,依次选择。

选择时分两种情况:

  • 直接选择 \(\left\lceil\dfrac{L}{2^{i-1}}\right\rceil\) 个当前瓶子。

  • 选择 \(\left\lfloor\dfrac{L}{2^{i-1}}\right\rfloor\) 个当前瓶子,用后面的瓶子再去算剩下的 \(L-2^{i-1}\cdot\left\lfloor\dfrac{L}{2^{i-1}}\right\rfloor\) 容量。

两种情况取 \(\min\) 即可。

Code

#include<bits/stdc++.h>
using namespace std;

struct bot
{
    int V, w;
    bot(int v, int W): V(v), w(W) {}
    auto operator<=>(bot &b) {return 1ll*b.V*w<=>1ll*V*b.w;}
};

vector<bot> con, bts;

int64_t calc(int n, vector<bot>::iterator it)
{
    int64_t ret=ceil(1.00*n/it->V)*it->w;
    if(n%it->V==0||next(it)==bts.end()) return ret;
    else return min(ret, 1ll*(n/it->V)*it->w+calc(n%it->V, next(it)));
}

int main()
{
    int n, l;
    cin>>n>>l;
    for(int i=0, t;i<n;i++)
        cin>>t, con.emplace_back(1<<i, t);
    sort(con.begin(), con.end());
    for(auto v:con)
        if(bts.empty()||v.V<bts.back().V) 
            bts.emplace_back(v);
    cout<<calc(l, bts.begin());
}
posted @ 2024-09-09 21:09  Jimmy-LEEE  阅读(19)  评论(0)    收藏  举报