Shopping Offers

 

1.解析

题目大意,给定每个商品的价值和优惠券(优惠券可以重复使用),求解所购买商品最少花多少钱。

2.分析

我最初看到这道题的时候,求最值,以为是DP,但在设计的过程中,发现有个问题,就是所取到的值并不是局部的最优解,因为不单要考虑优惠券,而且还要考虑无法使用优惠券的那部分的钱,所以不是DP。参考@Grandyang博主的思路,发现其实采用深度优先检索是最简便的,利用一个临时变量表示是否当前的优惠券可用,若可用,则继续搜索,若不可用,恢复之前的状态,搜索下一个。蛮简单的,具体实现如下:

class Solution {
public:
    int shoppingOffers(vector<int>& price, vector<vector<int>>& special, vector<int>& needs){
        int res = 0, n = price.size();
        for (int i = 0; i < n; ++i)
            res += price[i] * needs[i];
        for (auto offer : special){ //每次遍历所有的优惠券,因为优惠券的使用数量不限
            bool isValid = true;
            for (int i = 0; i < needs.size(); ++i){ //假设当前的优惠券可用
                if (needs[i] < offer[i]) isValid = false; //若检测到不可用,标记
                needs[i] -= offer[i];
            }
            if (isValid)
                res = min(res, shoppingOffers(price, special, needs) + offer.back());
            for (int i = 0; i < needs.size(); ++i){ //恢复不使用优惠券前的状态
                needs[i] += offer[i];
            }
        }
        
        return res;
    }
};

[1]https://www.cnblogs.com/grandyang/p/7261663.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值