Party Lemonade

很久没做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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值