Shopping Offers in C++


Suppose there is a store, there are some items to sell. Each item has some price. However, there are some special offers, and a special offer consists of one or more different kinds of items with a sale price. So we have the list of prices, a set of special offers, and the number we need to buy for each item. The task is to find the lowest price we have to pay for exactly certain items as given, where we could make optimal use of the special offers.

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

So if the input is like [2,5], [[3,0,5], [1,2,10]] and [3,2], then the output will be 14. This is because there are two kinds of items, A and B. Their prices are $2 and $5 respectively. In the special offer 1, we can pay $5 for 3A and 0B. In special offer 2, we can pay $10 for 1A and 2B. We need to buy 3A and 2B, so we may pay $10 for 1A and 2B (special offer 2), and $4 for 2A.

To solve this, we will follow these steps −

  • Define a map called memo

  • Define a method called directPurchase(), this takes price and needs arrays

  • ret := 0

  • for i in range 0 to size of price array – 1

    • ret := ret + price[i] * needs[i]

  • return ret

  • Define one helper method. This will take price array, the special offer matrix, array needs and index −

  • if memo has needs then return memo[needs]

  • ret := directPurchase(price, need)

  • for i in range index to number of rows of special offer matrix – 1

    • if needs[j] < special[i, j], then set ok := false, and come out from the loop

    • insert need[j] – special[i, j] into temp array

  • if ok is true, then

    • op1 := last column element of special[i] + helper(price, special, temp, i)

    • ret := minimum of ret and op1

  • memo[needs] := ret and return

  • From the main method do the following −

  • return helper(price, special, needs, 0)

Example (C++)

Let us see the following implementation to get a better understanding −

 Live Demo

#include <bits/stdc++.h>
using namespace std;
class Solution {
   public:
   map <vector <int> , int> memo;
   int shoppingOffers(vector<int>& price, vector<vector<int>>& special, vector<int>& needs) {
      return helper(price, special, needs, 0);
   }
   int helper(vector <int>& price, vector < vector <int> >& special, vector <int>& needs, int idx){
      if(memo.count(needs)) return memo[needs];
      int ret = directPurchase(price, needs);
      for(int i = idx; i < special.size(); i++){
         vector <int> temp;
         bool ok = true;
         for(int j = 0; j < special[i].size() - 1; j++){
            if(needs[j] < special[i][j]) {
               ok = false;
               break;
            }
            temp.push_back(needs[j] - special[i][j]);
         }
         if(ok){
            int op1 = special[i][special[i].size() - 1] + helper(price, special, temp, i);
            ret = min(ret, op1);
         }
      }
      return memo[needs] = ret;
   }
   int directPurchase(vector <int>& price, vector <int>& needs){
      int ret = 0;
      for(int i = 0; i < price.size(); i++){
         ret += price[i] * needs[i];
      }
      return ret;
   }
};
main(){
   vector<int> v1 = {2,5};
   vector<vector<int>> v2 = {{3,0,5},{1,2,10}};
   vector<int> v3 = {3,2};
   Solution ob;
   cout << (ob.shoppingOffers(v1, v2, v3));
}

Input

[2,5]
[[3,0,5],[1,2,10]]
[3,2]

Output

14

Updated on: 02-May-2020

213 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements