小扣在秋日市集购买了一个古董键盘。由于古董键盘年久失修,键盘上只有 26 个字母 a~z 可以按下,且每个字母最多仅能被按 k 次。
小扣随机按了 n 次按键,请返回小扣总共有可能按出多少种内容。由于数字较大,最终答案需要对 1000000007 (1e9 + 7) 取模。
示例 1:
输入:k = 1, n = 1
输出:26
解释:由于只能按一次按键,所有可能的字符串为 "a", "b", ... "z"
示例 2:
输入:k = 1, n = 2
输出:650
解释:由于只能按两次按键,且每个键最多只能按一次,所有可能的字符串(按字典序排序)为 "ab", "ac", ... "zy"
提示:
1 <= k <= 5
1 <= n <= 26*k
思路:定义dp[i][j]:表示前i种字母按了j次的方案数,之后就是结合组合数进行转移即可【插空法】。
class Solution {
private static long[][] c;
private static final int mod = 1000000007;
public int keyboard(int k, int n) {
long[][] dp = new long[27][135];
dp[0][0] = 1;
for (int i = 1; i <= 26; i++)
for (int j = 0; j <= k * (i - 1); j++)
for (int r = 0; r <= k; r++)
dp[i][j + r] = (dp[i][j + r] + C(j, r) * dp[i - 1][j]) % mod;
return (int) (dp[26][n] % mod + mod) % mod;
}
private long C(long n, long m) {
long ans = 1;
for (int i = 1; i <= m; i++)
ans = ans * (n + i);
for (int i = 1; i <= m; i++)
ans /= i;
return ans % mod;
}
}