Codeforces 913C:Party Lemonade(贪心)
C. 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
4 12
20 30 70 90
150
4 3
10000 1000 100 10
10
4 3
10 100 1000 10000
30
5 787787787
123456789 234567890 345678901 456789012 987654321
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种不同规格的饮料,容量分别为2i-1L,并给出每种饮料的价格。
现在题目要求至少购买 l升的饮料,最少需要多少钱。
思路
仔细一看,以为是背包,又读了一遍题,貌似是个sb贪心题
但是这个贪心又有点dp的感觉,因为不能只贪最便宜的,每次贪心要对两种状态进行比较,不断地在两种状态间转换
首先按照每个饮料的单价(每升多少钱)升序排序,然后会有两种状态:
- 全部买最便宜的那种饮料,直到买的数量大于等于L
- 最便宜的饮料买的尽可能的多,但是不要超过L,剩下的部分作为L返回第一步
代码
1 #include <bits/stdc++.h> 2 #define ll long long 3 #define ull unsigned long long 4 #define ms(a,b) memset(a,b,sizeof(a)) 5 const int inf=0x3f3f3f3f; 6 const ll INF=0x3f3f3f3f3f3f3f3f; 7 const int maxn=1e6+10; 8 const int mod=1e9+7; 9 const int maxm=1e3+10; 10 using namespace std; 11 struct wzy 12 { 13 ll bigness; 14 ll money; 15 double price; 16 }p[maxn]; 17 bool cmp(wzy u,wzy v) 18 { 19 return u.price<v.price; 20 } 21 int main(int argc, char const *argv[]) 22 { 23 #ifndef ONLINE_JUDGE 24 freopen("/home/wzy/in.txt", "r", stdin); 25 freopen("/home/wzy/out.txt", "w", stdout); 26 srand((unsigned int)time(NULL)); 27 #endif 28 ios::sync_with_stdio(false); 29 cin.tie(0); 30 int n; 31 ll l; 32 cin>>n>>l; 33 for(int i=1;i<=n;i++) 34 { 35 cin>>p[i].money; 36 p[i].bigness=(1LL<<(i-1)); 37 p[i].price=1.0*p[i].money/p[i].bigness; 38 } 39 sort(p+1,p+1+n,cmp); 40 ll L=l; 41 ll ans=INF; 42 ll res1=0,res2=0; 43 while(L>0) 44 { 45 for(int i=1;i<=n;i++) 46 { 47 // 全买这个饮料 48 res1=res2+ceil(1.0*L/p[i].bigness)*p[i].money; 49 ans=min(ans,res1); 50 // 多余的部分买别的 51 res2+=L/p[i].bigness*p[i].money; 52 L-=(p[i].bigness*(L/p[i].bigness)); 53 } 54 } 55 ans=min(ans,res2); 56 cout<<ans<<endl; 57 #ifndef ONLINE_JUDGE 58 cerr<<"Time elapsed: "<<1.0*clock()/CLOCKS_PER_SEC<<" s."<<endl; 59 #endif 60 return 0; 61 }