题目来源:https://leetcode.com/contest/weekly-contest-105/problems/number-of-music-playlists/
问题描述
920. Number of Music Playlists
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:
0 <= K < N <= L <= 100
------------------------------------------------------------
题意
给定N首不同的歌,要求生成长度为L的歌单,歌单中每首歌放完后要等放过其他K首歌才能再放。求生成的不同的歌单的数量。
------------------------------------------------------------
思路
思路参考了清华大学计算机系算协比赛部的思路LeetCode周赛#105题解。动态规划。
dp[i][j] = 用j首不同的歌产生长度为i的歌单的种数
dp[i][j] = dp[i-1][j-1]*(N-(j-1))// 第i首歌不是前(j-1)首歌中的某一首歌
+ dp[i-1][j]*(j-K) // 第i首歌是前j首歌中的某一首歌,与第(i-K):(i-1)首歌不同
边界条件: dp[0][0] = 1
------------------------------------------------------------
代码
class Solution {
public:
const long long MOD = (long long) (1e9+7);
int numMusicPlaylists(int N, int L, int K) {
long long dp[105][105] = {};
int i, j;
dp[0][0] = 1;
for (i=1; i<=L; i++)
{
for (j=1; j<=min(N,i); j++)
{
dp[i][j] = dp[i-1][j-1]*(N-j+1);
dp[i][j] %= MOD;
dp[i][j] += dp[i-1][j]*max(0, j-K);
dp[i][j] %= MOD;
}
}
return dp[L][N];
}
};