classSolution{public:intnumMusicPlaylists(intn,intgoal,intk){this->n=n;this->k=k;// dp[i][j] := # of playlists with i songs and j different songsdp.resize(goal+1,vector<long>(n+1,-1));returnplaylists(goal,n);}private:constexprstaticintkMod=1'000'000'007;intn;intk;vector<vector<long>>dp;longplaylists(inti,intj){if(i==0)returnj==0;if(j==0)return0;if(dp[i][j]>=0)returndp[i][j];dp[i][j]=playlists(i-1,j-1)*(n-(j-1));// Last song is newdp[i][j]+=playlists(i-1,j)*max(0,j-k);// Last song is oldreturndp[i][j]%=kMod;}};
classSolution{publicintnumMusicPlaylists(intn,intgoal,intk){this.n=n;this.k=k;// dp[i][j] := # of playlists with i songs and j different songsdp=newlong[goal+1][n+1];Arrays.stream(dp).forEach(row->Arrays.fill(row,-1));return(int)playlists(goal,n);}privatestaticfinalintkMod=1_000_000_007;privateintn;privateintk;privatelong[][]dp;privatelongplaylists(inti,intj){if(i==0)returnj==0?1:0;if(j==0)return0;if(dp[i][j]>=0)returndp[i][j];dp[i][j]=playlists(i-1,j-1)*(n-(j-1));// Last song is newdp[i][j]+=playlists(i-1,j)*Math.max(0,j-k);// Last song is oldreturndp[i][j]%=kMod;}}
classSolution{public:intnumMusicPlaylists(intn,intgoal,intk){constexprintkMod=1'000'000'007;// dp[i][j] := # of playlists with i songs and j different songsvector<vector<long>>dp(goal+1,vector<long>(n+1));dp[0][0]=1;for(inti=1;i<=goal;++i)for(intj=1;j<=n;++j){dp[i][j]+=dp[i-1][j-1]*(n-(j-1));// Last song is newdp[i][j]+=dp[i-1][j]*max(0,j-k);// Last song is olddp[i][j]%=kMod;}returndp[goal][n];}};