分析
因为容量为 \(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());
}
标签:right,return,int,题解,Lemonade,ret,瓶子,dfrac,Party
From: https://www.cnblogs.com/redacted-area/p/18405334