Codeforces 913C Party Lemonade

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


很高兴,这道让我念念不忘的题今天终于被我AC啦


题意: 给你n个瓶子,每个瓶子的体积从1 2 4 816.... 这样变化下去,然后给你 L升要装的东西,问你最小的花费。


解题思路:


一开始以为是背包问题,但是1e9不能背包啊,除非是用vector,但是也很困难,实现不大。然后我就换了种想法。贪心试试吧


先预处理一下每一种类型的瓶子的最小花费,设当前的瓶子的花费为a,下一种瓶子的花费为b,

从头到尾 :如果2*a<b 那么我们就更新b的值

从尾到头: 如果b<a的话 就说明你买当前的瓶子 还不如买比它体积大的那种 还省好多钱尼

当预处理完后 ,存每个类型瓶子的花费的数组的意义就变成了当前这个类型的瓶子的最小花费

 然后我们先选最大的,先用最大的装满。然后这个L一定可以由x个最大的+L-x*max这两部分组成。然后我们只需要管剩下的就行。然后每次暴力把多余的部分用比当前这个瓶子还要小的瓶子装起来,选最优的那一种。直到处理到第1种。然后就是答案了。

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn=33;
long long flag[maxn],num[maxn],n,m,te[maxn];
int main(){
	int i,j;
	scanf("%I64d%I64d",&n,&m);
	flag[1]=1;
	for(i=1;i<=n;i++){
		scanf("%I64d",&num[i]);
		if(i!=1) flag[i]=2*flag[i-1];
	}
	for(i=1;i<=n-1;i++){
		if(2*num[i]<num[i+1])
			num[i+1]=2*num[i];
	}
	for(i=n;i>1;i--){
		if(num[i]<num[i-1])
			num[i-1]=num[i];
	}
	memset(te,0,sizeof(te));
	long long t=m/flag[n]+((m%flag[n])?1:0);
	te[n]=t;
	long long ans=t*num[n];
	long long sum=0;
	int tt=0;
	for(i=n-1;i>=1;i--){
		te[i+1]--;
		te[i]+=2;
		sum=0;
		for(j=n;j>=i;j--){
			if(te[j]){
				sum+=te[j]*flag[j];
			}
		}
		while(sum>=m&&te[i]){
			sum-=flag[i];
			te[i]--;
		}
		te[i]++;
		long long ans2=0;
		for(j=n;j>=1;j--){
			if(te[j]){
				ans2+=(long long)te[j]*num[j];
			}
		}
		if(ans2<ans){
			ans=ans2;
		}
	}
	printf("%I64d\n",ans);
	return 0;
}


我还是不太会二进制,需要补。。。

long long ans = 0,res = 1e18;
for (int i = 30; i >= 0; --i){
	if (l & (1ll << i))
		ans += num[i + 1];
	res = min(ans + num[i + 1], res);
}

我这几天发现一个问题,就是解题人数超过500的就是一道可以解出来的水题。
顺利的怀疑人生。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值