满减优惠

For study!

Posted by Winray on August 13, 2016
  • 题目介绍:

    时间限制:10000ms
    单点时限:1000ms
    内存限制:256MB
    
    描述
    最近天气炎热,小Ho天天宅在家里叫外卖。他常吃的一家餐馆一共有N道菜品,价格分别是A1, A2, ... AN元。
    并且如果消费总计满X元,还能享受优惠。小Ho是一个不薅羊毛不舒服斯基的人,他希望选择若干道不同的菜品,
    使得总价在不低于X元的同时尽量低。
    你能算出这一餐小Ho最少消费多少元吗?
         
    Input
    第一行包含两个整数N和X,(1 <= N <= 20, 1 <= X <= 100)
    
    第二行包含N个整数A1, A2, ..., AN。(1 <= Ai <= 100) 
         
    Output
    输出最少的消费。如果小Ho把N道菜都买了还不能达到X元的优惠标准,输出-1。
         
    Sample Input
    10 50
    9 9 9 9 9 9 9 9 9 8
    Sample Output
    53
    
  • 转发、借鉴

  • 思路:
    • 暴力枚举。
    • 巧妙利用二进制。
  • 具体代码如下:

    #include <iostream>
    #include <vector>
      
    using namespace std;
      
    int main(void)
    {
        int n, x, sum = 0;
        cin >> n >> x;
        vector<int> nums(n);
        for (int i = 0; i < n; ++i) {
            cin >> nums[i];
            sum += nums[i];
        }
        if (sum < x) {
            cout << -1 << endl;
            return 0;
        }
      
        int ret = sum;
        for (int i = 1, iend = 1 << n; i < iend; ++i) {
            if (ret == x)
                break;
            int cur = 0;
            for (int j = 0; j < n; ++j) {
                if (((1 << j) & i)) // select jth number from nums
                    cur += nums[j];
                if (cur >= x) { // because there is no negative number in nums
                    break;
                }
            }
            // update minimum value greater than x
            if (cur >= x && cur < ret)
                ret = cur;
        }
        cout << ret << endl;
        return 0;
    }