Party Lemonade CodeForces
A New Year party is not a New Year party without lemonade! As usual, you are expecting a lot of guests, and buying lemonade has already become a pleasant necessity.
Your favorite store sells lemonade in bottles of n different volumes at different costs. A single bottle of type i has volume 2i - 1 liters and costs c
You want to buy at least L liters of lemonade. How many roubles do you have to spend?
Input
The first line contains two integers n and L (1 ≤ n ≤ 30; 1 ≤ L ≤ 109) — the number of types of bottles in the store and the required amount of lemonade in liters, respectively.
The second line contains n integers c1, c2, ..., cn (1 ≤ ci ≤ 109) — the costs of bottles of different types.
Output
Output a single integer — the smallest number of roubles you have to pay in order to buy at least L liters of lemonade.
Examples
Input
4 12 20 30 70 90
Output
150
Input
4 3 10000 1000 100 10
Output
10
Input
4 3 10 100 1000 10000
Output
30
Input
5 787787787 123456789 234567890 345678901 456789012 987654321
Output
44981600785557577
Note
In the first example you should buy one 8-liter bottle for 90 roubles and two 2-liter bottles for 30 roubles each. In total you'll get 12 liters of lemonade for just 150 roubles.
In the second example, even though you need only 3 liters, it's cheaper to buy a single 8-liter bottle for 10 roubles.
In the third example it's best to buy three 1-liter bottles for 10 roubles each, getting three liters for 30 roubles.
思路:
按照店鋪單位價值排序一下,然後貪心加動態規劃
程式碼:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
int n;
struct TA_
{
ll v,w;
TA_() {}
TA_(ll a,ll b):v(a),w(b) {}
bool operator< (const TA_& c)
{
//return (double)v/w > (double)c.v/c.w; //單位價值大的在前
return v * c.w > c.v * w; //交叉相乘
}
} ta[35]; //店
ll solve(ll left,ll cost,int i)//剩餘要買、當前花費、當前店鋪
{
ll m=left/ta[i].v; //要買的桶數,儘可能多的在當前店鋪買
cost+=m*ta[i].w; //更新花費
left-=m*ta[i].v; //更新要買
if(left==0) return cost; //如果剛好買完
if(i==n) return cost+ta[i].w; //如果還有要買且已經在最後一間店
ll temp=solve(left,cost,i+1); //去下一間店看看
return min(temp,cost+ta[i].w); //在當前店再買一桶,或者去下一間店買剩餘的
}
int main(void)
{
ll l;
scanf("%d %lld",&n,&l);
scanf("%lld",&ta[1].w);
ta[1].v=1;
for(int i=2;i<=n;i++) {
scanf("%lld",&ta[i].w);
ta[i].v=ta[i-1].v<<1;
}
sort(ta+1,ta+n+1);
printf("%lld\n",solve(l,0,1));
return 0;
}