Codeforces Hello 2018!C

emmmmm怎么说呢,,,半年了,,,几乎也没有什么长进,,,cf  div.2依旧只能做AB,,,怀疑人生

然而,人还是要有梦想呀(最近掉坑三月的狮子无法自拔,大冬天的,暖哭QAQ)

总之,新的一年加油(ง •_•)ง,学的慢没关系,努力努力再努力,思维不好也没关系,思维也可以练呀(虽然内心是崩溃的)

最可怕的是望着差距止步不前。

C.Party Lemonade

emmmmmm没做出来,一眼看上去像完全背包,然而……并没有那么复杂……好好看题啊orz,题目条件不会乱给的orz

第i+1个瓶子的容量为2^i,然后……emmmm二进制有木有(i∈[0,n))

设dp[i]为买2^i的最小花费

买2^i可以买两瓶2^i-1也可以买一瓶2^i+1,那么对于2^i-1的花费最小为dp[i]=min(dp[i],dp[i-1]*2),然后逆序再扫一遍dp[i]=min(dp[i+1],dp[i])

经过两次循环,dp可以更新为最小花费。

然后来考虑一下目标量L的最小花费,L同样可以表示为二进制,二进制位为1则取dp[i],为0则取min(当前花费,dp[i])

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAX=1e3+5;
ll dp[35];
ll sum=0,n,l;
int main()
{
    cin>>n>>l;
    memset(dp,0x3f3f3f,sizeof(dp));
    for(int i=0;i<n;i++)
        cin>>dp[i];
    for(int i=1;i<n;i++)
        dp[i]=min(dp[i],dp[i-1]*2);
    for(int i=n-2;i>0;i--)
        dp[i]=min(dp[i+1],dp[i]);
    for(int i=n;i<31;i++)
        dp[i]=dp[i-1]<<1;
    for(int i=0;i<31;i++)
    {
        if(l&(1<<i)) sum+=dp[i];
        else if(sum>dp[i]) sum=dp[i];
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Egoist-/p/8278066.html