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; }