Formatted question description: https://leetcode.ca/all/920.html

920. Number of Music Playlists (Hard)

Your music player contains N different songs and she wants to listen to L (not necessarily different) songs during your trip.  You create a playlist so that:

  • Every song is played at least once
  • A song can only be played again only if K other songs have been played

Return the number of possible playlists.  As the answer can be very large, return it modulo 10^9 + 7.

 

Example 1:

Input: N = 3, L = 3, K = 1
Output: 6
Explanation: There are 6 possible playlists. [1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1].

Example 2:

Input: N = 2, L = 3, K = 0
Output: 6
Explanation: There are 6 possible playlists. [1, 1, 2], [1, 2, 1], [2, 1, 1], [2, 2, 1], [2, 1, 2], [1, 2, 2]

Example 3:

Input: N = 2, L = 3, K = 1
Output: 2
Explanation: There are 2 possible playlists. [1, 2, 1], [2, 1, 2]

 

Note:

  1. 0 <= K < N <= L <= 100

Related Topics:
Dynamic Programming

Solution 1. DP

Let dp[i][j] be the number of playlists of length i that have exactly j unique songs. The answer is dp[L][N].

To get dp[i][j], we consider the i-1-th song:

  • It has not been played before. This is the first time it’s played. The first i - 1 songs must have j - 1 unique songs. We can choose from N - (j - 1) new songs. So dp[i - 1][j - 1] * (N - j + 1) cases.
  • It has been played before. The first i - 1 songs must have j unique songs. This song is one of the j unique songs. The [i - K, i - 1] songs must be unique and the last song can’t be of these K songs. So we can only choose from the remaining j - K songs. dp[i - 1][j] * max(j - K, 0)
// OJ: https://leetcode.com/problems/number-of-music-playlists/

// Time: O(NL)
// Space: O(NL)
// Ref: https://leetcode.com/problems/number-of-music-playlists/solution/
class Solution {
public:
    int numMusicPlaylists(int N, int L, int K) {
        long dp[101][101] = {}, mod = 1e9+7;
        dp[0][0] = 1;
        for (int i = 1; i <= L; ++i) {
            for (int j = 1; j <= N; ++j) {
                dp[i][j] += dp[i - 1][j - 1] * (N - j + 1);
                dp[i][j] += dp[i - 1][j] * max(j - K, 0);
                dp[i][j] %= mod;
            }
        }
        return dp[L][N];
    }
};

Java

class Solution {
    public int numMusicPlaylists(int N, int L, int K) {
        final int MODULO = 1000000007;
        long[][] dp = new long[L + 1][N + 1];
        dp[0][0] = 1;
        for (int i = 1; i <= L; i++) {
            for (int j = 1; j <= N; j++) {
                dp[i][j] += dp[i - 1][j - 1] * (N - j + 1) + dp[i - 1][j] * Math.max(j - K, 0);
                dp[i][j] %= MODULO;
            }
        }
        return (int) dp[L][N];
    }
}

All Problems

All Solutions