zoukankan      html  css  js  c++  java
  • [Leetcode]638. Shopping Offers

    链接:LeetCode638

    在LeetCode商店中, 有许多在售的物品。
    然而,也有一些大礼包,每个大礼包以优惠的价格捆绑销售一组物品。
    现给定每个物品的价格,每个大礼包包含物品的清单,以及待购物品清单。请输出确切完成待购清单的最低花费。
    每个大礼包的由一个数组中的一组数据描述,最后一个数字代表大礼包的价格,其他数字分别表示内含的其他种类物品的数量。
    任意大礼包可无限次购买。

    示例 1:
    输入: ([2,5], [[3,0,5],[1,2,10]], [3,2])
    输出: (14)
    解释:
    有A和B两种物品,价格分别为¥2和¥5。
    大礼包1,你可以以¥5的价格购买3A和0B。
    大礼包2, 你可以以¥10的价格购买1A和2B。
    你需要购买3个A和2个B, 所以你付了¥10购买了1A和2B(大礼包2),以及¥4购买2A。

    相关标签:记忆化搜索

    难点在于构造备忘录,如果用数组的话,维数太大,操作起来比较麻烦。可以转换为str类型,也可以将needs数组的每一位连接起来构成一个10进制数,例如题中给的第一个例子,needs数组为3,2,那么就定义一个need=32,用来代替needs数组,然后用一个map结构来储存已经求到的子问题的解。本题的递归关系比较简单,首先要用单价来求不同needs对应的花费的初始值,定义一个数组temp来储存选了一个礼包后needs数组的变化,即temp=needs-special[i],在减的过程中如果出现小于0的值即表示购买当前礼包后超过了代购清单,就退出。然后自顶向下的求出解。代码如下:

    python:

    class Solution:
        def shoppingOffers(self, price: List[int], special: List[List[int]], needs: List[int]) -> int:
            dic = {}
            res = self.dfs(price,special,needs,dic)
            return res
    
        def dfs(self,price,special,needs,dic):
            if str(needs) in dic:
                return dic[str(needs)]
            result = 0
            for i in range(len(price)):
                result += price[i]*needs[i]
            for sp in special:
                new = needs[:]
                for i in range(len(new)):
                    new[i] -= sp[i]
                    if new[i] < 0:
                        break
                else:
                    result = min(result,sp[-1]+self.dfs(price,special,new,dic))
            dic[str(needs)] = result
            return result
    

    C++:

    class Solution {
    public:
        int getKey(vector<int> needs) {
            int n = needs.size();
            int result = 0;
            for(int i=0;i<n;i++) {
                result = result * 10 + needs[i];
            }
            return result;
        }
    
    
        int shoppingOffers(vector<int>& price, vector<vector<int>>& special, vector<int>& needs) {
            unordered_map<int,int> map;
            int res = dfs(price, special, needs, map);
            return res;
        }
    
        int dfs(vector<int>& price,vector <vector<int>>& special, vector<int>& needs,unordered_map<int,int> map) {
            int key = getKey(needs);
            if (map[key])
                return map[key];
            int result = 0;
            for (int i = 0;i<price.size();i++){
                result += price[i] * needs[i];
            }
    
            for (int i = 0;i<special.size();i++){
                vector<int> temp = needs;
                int j;
                for (j=0;j<price.size();j++){
                    temp[j] -= special[i][j];
                    if(temp[j]<0){
                        break;
                    }
                }
                if (j == price.size()){
                    result = min(result,special[i][j]+dfs(price,special,temp,map));
                }
            }
            map[key] = result;
            return result;
        }
    
    };
    

    参考:
    LeetCode_638(动态规划)

  • 相关阅读:
    测试用例模板和编写目的
    使用AndroidStudio配置码云时,提醒following remotes are already on gitee git
    win10操作系统查看电池损耗,电池使用时间
    windows技巧03----win的一些组合键
    windows技巧02---------输入特殊字符
    windows技巧01------------记事本默认保存修改时间
    word2010如何让第一页不显示页码
    docker镜像管理基础
    docker基础用法
    SaltStack进阶
  • 原文地址:https://www.cnblogs.com/hellojamest/p/11823794.html
Copyright © 2011-2022 走看看