很久没做CF了,今天6:30起床复习,考完最后两门寻思终于能好好打CF了,结果这题做一半睡着了-:
http://codeforces.com/contest/913/problem/C
题意:
有n家店铺,每个店铺有一种商品(无限个),每种商品有体积(2的i-1次方),每种商品有价格c[i],问至少买l体积的物品最少需要花费多少钱?
思路:
由于l的范围特别大,所以不能直接背包做,然后我们想一想为什么背包问题不能贪心去做,本质上是因为性价比最高的物体会可能导致空间无法充分利用,而这题则不存在这个问题(可以从二进制的角度去想,比如把l写成二进制,那么最高位的1可以由所有商品买若干个获得,且总是需要获得,所以对于这个最高位的1来说他是可以贪心的。),所以我们可以贪心地尽量多地选取性价比高的物品。
然后再贪心选完了之后还要考虑余下的部分:可以再继续选一个当前物品(体积会超出但是价格却是最低的,或者余下的部分继续搜索,需要加个记忆化或者先排个序贪心的去选)。
#include<bits/stdc++.h>
using namespace std;
long long cost[50],n;
map<long long ,long long> mp;
long long getMinCost(long long l)
{
if(mp[l]) return mp[l];
if(l==0) return 0;
long long q=1<<(n-1);
long long ret=1ll<<60;
for(long long i=n-1;i>=0;i--)
{
if(q>=l) {
ret=min(ret,cost[i]);
}
else {
long long cnt=l/q;
ret=min(ret,min(cost[i]*(cnt+1),cost[i]*cnt+getMinCost(l%q)));
}
q>>=1;
}
return mp[l]=ret;
}
int main()
{
long long l;
cin>>n>>l;
for(long long i=0;i<n;i++)
{
scanf("%lld",&cost[i]);
}
cout<<getMinCost(l)<<endl;
}