[Code Forces] 913 - Party Lemonade - 贪心

C. Party Lemonade
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

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 - 1liters and costs ci roubles. The number of bottles of each type in the store can be considered infinite.

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 ≤ 301 ≤ 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.



n 瓶柠檬水,第 i 瓶的体积为 2^(i - 1),价格为 v_i
你需要买 m 体积的柠檬水 
求最小花费

很显然的一个贪心是算出每份柠檬水单位体积的价格然后排序
但是因为有除法  会有精度问题
所以注意到每瓶柠檬水的体积都是2的倍数
所以我们统一到体积最高进行排序
除就变成乘了(齐齐真厉害)
再根据排序后的结果从小到大贪心
因为允许你所买的柠檬水的体积超过原本所需的柠檬水的体积
通过递归求解
对于当前柠檬水
比较一下 剩下的直接买光 与 买下一份  的代价
就好了
注意一下细节  爆 int

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

const int N = 110;

struct Node
{
    int x;  ///体积
    int y;  ///cost
    LL z;   ///统一体积后的花费
};

bool cmp(Node a, Node b)
{
    return a.z < b.z;
}

Node node[N];
int tem[N];
int n, m;

LL solve(int x, LL ans)
{
    LL q;
    LL t;

    if(m <= 0){
        return ans;
    }
    q = m / node[x].x;
    m -= q * node[x].x;
    ans += q * node[x].y;
    t = solve(x + 1, ans);
    if(ans + node[x].y < t){
        return ans + node[x].y;
    }
    else{
        return t;
    }
}

int main(int argc, char const *argv[])
{
	tem[0] = 1;
	for(int i = 1; i <= 30; i ++){
		tem[i] = tem[i - 1] * 2;
	}
	while(scanf("%d%d", &n, &m) == 2){
		for(int i = 0; i < n; i ++){
            node[i].x = tem[i];
			scanf("%d", &node[i].y);
			node[i].z = 1ll * node[i].y * tem[n - i - 1];   ///
		}
		sort(node, node + n, cmp);
		printf("%lld\n", solve(0, 0));
	}

	return 0;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值