Your music player contains n different songs. You want to listen to goal songs (not necessarily different) during your trip. To avoid boredom, you will 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.
Given n, goal, and k, return the number of possible playlists that you can create. Since the answer can be very large, return it modulo 109 + 7.
Example 1:
Input: n = 3, goal = 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], and [3, 2, 1].
Example 2:
Input: n = 2, goal = 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], and [1, 2, 2].
Example 3:
Input: n = 2, goal = 3, k = 1
Output: 2
Explanation: There are 2 possible playlists: [1, 2, 1] and [2, 1, 2].
Constraints:
抄的官方的答案。
dp[l][n]是 l 首歌的歌单, n 首歌的排列组合数量, 那 dp[l][n]是由两部分组合起来的, 一部分是 dp[l-1][n-1]外加一首 n-1 之外的新歌, 另一部分是 dp[l-1][n]外加 n 当中的一首歌的重复, 第一种情况我们可以在 n-1 之外选择任意一首歌加到歌单中, 所以可选歌的数量是 total-(n-1), 第二种情况我们要判断前面是否已经播放了 k 首不同的歌, 所以我们要比较 n 和 k 的大小, 只有 n > k 的时候我们才能将这种情况下的排列组合数量加到答案中。
impl Solution {
pub fn num_music_playlists(n: i32, goal: i32, k: i32) -> i32 {
let mut dp = vec![vec![0; n as usize + 1]; goal as usize + 1];
dp[0][0] = 1;
for i in 1..=goal {
for j in 1..=n {
dp[i as usize][j as usize] +=
dp[i as usize - 1][j as usize - 1] * (n - j + 1) as i64;
dp[i as usize][j as usize] +=
dp[i as usize - 1][j as usize] * (j - k).max(0) as i64;
dp[i as usize][j as usize] %= 1000000007;
}
}
dp[goal as usize][n as usize] as i32
}
}