• Party Lemonade


    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 ≤ 1e9) — 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 ≤ 1e9) — 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.

    SampleInput 1
    4 12
    20 30 70 90
    SampleOutput 1
    150
    SampleInput 2
    4 3
    10000 1000 100 10
    SampleOutput 2
    10
    SampleInput 3
    4 3
    10 100 1000 10000
    SampleOutput 3
    30
    SampleInput 4
    5 787787787
    123456789 234567890 345678901 456789012 987654321
    SampleOutput 4
    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.

    题目链接

    思路

    先观察发现仿佛跟二进制有关系,可以先得到第一个状态转移方程,计算出选择当前这个位置的这个值的最小花费是多少
    假设dp[i] 为选择第i个 的最小花费
    容易得到第一个状态转移方程
    dp[i] = min(dp[i - 1] * 2, arr[i]);
    这样可以得到当前这个位置的最小花费
    但是题目要求的是大于等于L,所以吧dp[i]状态变换成大于等于i的最小花费,其实很简单只要从大到小遍历一下,保存最小值即min(dp[i], dp[i + 1])
    但是考虑L所对应的二进制去dp
    可以得到第二个状态转移方程
    设dp2[i]为选择了当前这个位置对应的价值的最小值
    vids[i]代表i这个位置是否是L对应有值的二进制
    
    if(vids[i] == 1){
            dp2[i] = min(dp2[i - 1] + dp[i - 1] * 2, dp2[i - 1] + dp[i]);
    }
    else{
            dp2[i] = min(dp2[i - 1], dp[i]);
    }
    

    附上代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int MAXN = 35;
    long long dp[MAXN], arr[MAXN], dp2[MAXN];
    int vids[MAXN];
    int main(){
        ios::sync_with_stdio(false);
        int n, k;
        cin >> n >> k;
        for(int i = 1; i <= 32; i ++){
            arr[i] = __LONG_LONG_MAX__;
        }
        for(int i = 1; i <= n; i ++){
            cin >> arr[i];
        }
        dp[1] = arr[1];
        for(int i = 2; i <= 32; i ++){
            dp[i] = min(arr[i], dp[i - 1] * 2);
        }
        for(int i = 32 - 1; i >= 1; i --){
            dp[i] = min(dp[i], dp[i + 1]);
        }
        int num = 1;
        while(k){
            if(k & 1) vids[num] = 1;
            num ++;
            k >>= 1;
        }
        if(vids[1] == 1) dp2[1] = dp[1];
        else{
            dp2[1] = 0;
        }
        for(int i = 2; i <= 32; i ++){
            if(vids[i] == 1){
                dp2[i] = min(dp2[i - 1] + dp[i - 1] * 2, dp2[i - 1] + dp[i]);
            }
            else{
                dp2[i] = min(dp2[i - 1], dp[i]);
            }
        }
        cout << dp2[32] << endl;
        return 0;
    }
    
  • 相关阅读:
    设计模式C++学习笔记之一(Strategy策略模式)
    web服务器上某一中文名文件无法访问
    C++之多态性与虚函数
    常用的16个c/c++面试题
    C/C++ 笔试、面试题目大汇总
    利用jsoncpp将json字符串转换为Vector
    STL中vector、list、deque和map的区别
    C++类的继承中构造函数和析构函数调用顺序例子
    LNMP下Nginx 中文文件名或目录404无法访问的解决方法
    Python Web开发框架Django
  • 原文地址:https://www.cnblogs.com/qq136155330/p/11609963.html
Copyright © 2020-2023  润新知