题意:
小扣在秋日市集购买了一个古董键盘。
由于古董键盘年久失修,键盘上只有 26 个字母 a~ z 可以按下,且每个字母最多仅能被按 k 次。
小扣随机按了 n 次按键,请返回小扣总共有可能按出多少种内容。
由于数字较大,最终答案需要对 1000000007 ( 1e9 + 7 ) 取模。
数据范围:
1 <= k <= 5
1 <= n <= 26 * k
解法:
令d[ i] [ j] 表示使用前i种字符, 写了j个格子的方案数,
枚举第i+ 1 个字符的使用个数k, 那么:
d[ i+ 1 ] [ j+ p] + = d[ i] [ j] * C ( j+ p, p) ,
即从j+ p个格子中选出p个存放第i种字符, 然后剩下j个按序放d[ i] [ j] 的方案.
code:
const int mod= 1e9 + 7 ;
int d[ 26 + 1 ] [ 26 * 5 + 1 ] ;
class Solution {
public :
int C ( int n, int m) {
if ( m< 0 || m> n) return 0 ;
long long up= 1 ;
for ( int i= 1 ; i<= m; i++ ) up* = ( n- i+ 1 ) ;
long long down= 1 ;
for ( int i= 1 ; i<= m; i++ ) down* = i;
return ( int ) ( up/ down) % mod;
}
int keyboard ( int k, int n) {
memset ( d, 0 , sizeof d) ;
d[ 0 ] [ 0 ] = 1 ;
for ( int i= 0 ; i< 26 ; i++ ) {
for ( int j= 0 ; j<= k* i; j++ ) {
if ( ! d[ i] [ j] ) continue ;
for ( int p= 0 ; p<= k; p++ ) {
d[ i+ 1 ] [ j+ p] + = 1ll * d[ i] [ j] * C ( j+ p, p) % mod;
d[ i+ 1 ] [ j+ p] % = mod;
}
}
}
return d[ 26 ] [ n] ;
}
} ;