您的位置:首页 > 其它

Codeforces 913C Party Lemonade

2018-03-07 22:10 239 查看
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?
InputThe 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.
OutputOutput a single integer — the smallest number of roubles you have to pay in order to buy at least L liters of lemonade.

ExamplesInput
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
<
4000
div class="output">Output
44981600785557577
NoteIn 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
+((m%flag
)?1:0);
te
=t;
long long ans=t*num
;
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的就是一道可以解出来的水题。
顺利的怀疑人生。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: