Problem: SONGSHOP
There are N songs. The i
-th song costs p[i]
to purchase and brings v[i]
satisfaction to you if you buy it. Also, each song belongs to one album album[i]
and you can buy all the songs in an album for album_price[i]
(or you can buy all the songs individually). Given budget B
, what is the maximum satisfaction you can buy?
Observations
- Without albums, this would be the classical 0/1 knapsack problem solvable with dynamic programming (
dp[index][budget]
). - When we consider paying
album_price[i]
, we have to make sure we don’t pay for any individual song in that album. - The dp solution to knapsack problem works independent of the order of songs. This is an important degree of freedom we can benefit from!
Solution
First we sort songs by their album. Now, dp[i][b]
stores the maximum satisfaction we can get by using budget b
on items 1..i
. Now, there are 3 cases:
- we don’t take the song:
dp[i - 1][b]
- we take the song:
dp[i - 1][b - p[i]] + v[i]
- we take the whole album (we should consider this only on the last song of the album):
dp[ prev[i] ][ b - album_price[a] ] + album_v[a]
1.
1 prev[i]
returns the index of the last song from the previous album. In the image below, songs from the same album are colored with the same color.
The code would look like this: