638. Shopping Offers [LeetCode]

In LeetCode Store, there are some kinds of items to sell. Each item has a price.

However, there are some special offers, and a special offer consists of one or more different kinds of items with a sale price.

You are given the each item's price, a set of special offers, and the number we need to buy for each item. The job is to output the lowest price you have to pay for exactly certain items as given, where you could make optimal use of the special offers.

Each special offer is represented in the form of an array, the last number represents the price you need to pay for this special offer, other numbers represents how many specific items you could get if you buy this offer.

You could use any of special offers as many times as you want.

Example 1:

Input: [2,5], [[3,0,5],[1,2,10]], [3,2]
Output: 14
Explanation: 
There are two kinds of items, A and B. Their prices are $2 and $5 respectively. 
In special offer 1, you can pay $5 for 3A and 0B
In special offer 2, you can pay $10 for 1A and 2B. 
You need to buy 3A and 2B, so you may pay $10 for 1A and 2B (special offer #2), and $4 for 2A.

Example 2:

Input: [2,3,4], [[1,1,0,4],[2,2,1,9]], [1,2,1]
Output: 11
Explanation: 
The price of A is $2, and $3 for B, $4 for C. 
You may pay $4 for 1A and 1B, and $9 for 2A ,2B and 1C. 
You need to buy 1A ,2B and 1C, so you may pay $4 for 1A and 1B (special offer #1), and $3 for 1B, $4 for 1C. 
You cannot add more items, though only $9 for 2A ,2B and 1C.

Note:

  1. There are at most 6 kinds of items, 100 special offers.
  2. For each item, you need to buy at most 6 of them.
  3. You are not allowed to buy more items than you want, even if that would lower the overall price.


题目大意:这题的英文描述有点长,但实际上,看一下 example 和 note 就能明白题目要求我们干啥了。
给定三个 List ,分别表示各种商品的价格、特价组合和每种商品采购的需求。price 和 needs 的长度 n 表示商品的种类数。price[i] ,needs[i] 分别表示第 i 种商品的价格、需求量。special 列表中的每个元素,包含了组合中每种商品的数量和组合的购买价格。
每种组合的购买次数不限,但采购的商品不能有多余。要求出总价最低的采购方案的总金额。


思路概述:基本的思路就是采用DFS的递归算法,尝试用总需求减去 special 的供应量,如果新的需求不为负,深度优先递归,之后再加回减去的量。最后,需要对剩余需求量(没有匹配到合适的special)计算按单件采购的总金额,取较小的数返回



算法描述
<1>  result = max_value;
<2>  for i = 1 to special.size():
            offer = special[i];
            valid = true;  // 当前的 special 默认是有效的
            for j = 1 to needs.size():
                remain = needs[j] - offer[j];
                needs[j] = remain;
                if (valid && remain<0)    valid = false;  // special 供货量超过了需求量,不能采用该 special
            if (valid)    result = min(result,  go to<1> + offer.getPrice());  // 取最小的result
            for j = 1 to needs.size():
                needs[j] += offer[j];
<3>  for i = 1 to needs.size():
            nonOfferPrice += price[i] * needs[i];
<4>  return min(result, nonOfferPrice);


AC的代码如下
public class Solution {
    public int shoppingOffers(List price, List> special, List needs) {
        
        int result = Integer.MAX_VALUE;
        
        // dfs, try apply each offer to the needs, and then add back
        for (int i=0; i offer = special.get(i);
            // set offer application default valid
            boolean valid = true;   
            // try to apply offer
            for (int j=0; j





你可能感兴趣的:(leetcode算法题,LeetCode算法题,leetcode)