SRM531 Div1 Easy - NoRepeatPlaylist

問題

n曲からp曲選んで、以下の条件を全て満たすようなプレイリストを作りたい
① n曲全てを最低1個ずつ含む
② 同じ曲2つの間には異なる曲がm曲以上は挟まっている
何通りのプレイリストが作れるか

1 <= n <= 100
0 <= m <= n
n <= p <= 100

解法

dp[i][j]: i曲あり、n曲のうちj曲を使ったプレイリストの数
とすると答えはdp[p][n]であり、遷移は

・もう使った曲をまた使う場合
使う曲の候補は、制約②より直前に使ったm曲は使えないからj-m曲
dp[i+1][j] += dp[i][j] * (j-m)

・まだ使っていない曲を使う場合
n-j曲残っているから
dp[i+1][j+1] += dp[i][j] * (n-j)

class NoRepeatPlaylist {
public:
	int numPlaylists(int n, int m, int p) {
		ll dp[114][514] = {};
		dp[0][0] = 1;
		rep(i,p) rep(j,n+1) {
			(dp[i+1][j] += dp[i][j] * max(0, j-m)) %= mod;
			(dp[i+1][j+1] += dp[i][j] * (n-j)) %= mod;
		}
		return (int)dp[p][n];
	}
};

これが300点?