播放列表的数量
难度:
标签:
题目描述
代码结果
运行时间: 33 ms, 内存: 16.0 MB
/*
思路:
使用Java Stream对动态规划进行实现,但由于动态规划的特性,Stream实现并不是最佳选择,但可以尝试利用Stream来简化部分代码。
*/
import java.util.*;
import java.util.stream.*;
public class Solution {
public int numMusicPlaylists(int n, int goal, int k) {
int MOD = 1000000007;
long[][] dp = new long[goal + 1][n + 1];
dp[0][0] = 1;
IntStream.rangeClosed(1, goal).forEach(i -> {
IntStream.rangeClosed(1, Math.min(i, n)).forEach(j -> {
dp[i][j] = dp[i - 1][j - 1] * (n - j + 1) % MOD;
if (j > k) {
dp[i][j] = (dp[i][j] + dp[i - 1][j] * (j - k) % MOD) % MOD;
}
});
});
return (int) dp[goal][n];
}
}
解释
方法:
题解使用动态规划的方法,考虑dp数组存储在选择了P首歌曲,已经播放了S首不同的歌曲的情况下的播放列表数量。初始化dp数组为长度L-N+1,其中dp[i]表示选择了i+S首歌的所有可能的播放列表数量。然后通过两层循环,外层循环从2至N-K+1,内层从1至L-N+1,使用状态转移更新dp数组,最后将计算的结果乘以N的阶乘,以包括所有可能的不同歌曲的排列组合,最后结果取模10^9+7。
时间复杂度:
O((N-K)*(L-N) + N)
空间复杂度:
O(L-N+1)
代码细节讲解
🦆
如何正确理解和应用这里提到的动态规划数组dp[i]的定义?
▷🦆
题解中提到,初始化dp数组所有元素为1,这个初始化方法适用于所有情况吗,还是有特定的前提条件?
▷🦆
状态转移方程是如何从问题的限制条件(每首歌至少播放一次,且需间隔k首)中得出的?
▷🦆
dp数组和最终答案的计算中,为何需要将结果乘以N的阶乘?
▷