Leetcode-LCP 25. アンティークキーボード

トピック

LCP 25. アンティークキーボード

シャオコウさんは秋のマーケットでアンティークのキーボードを買いました。アンティークキーボードは老朽化しているため、キーボード上で押せる文字は a ~ z の 26 文字のみで、各文字は最大でも 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] を使用して、最初の j 文字を使用して押すことができる長さ i の文字列の総数を表します。j 番目の文字が x 回押されたとします (x の値の範囲は 0 ~ k)。
    ここに画像の説明を挿入します
    C(i, x) は、i 位置の中から x 位置を選択する方法が何通りあるかを示します。
  • C(n,m)の計算方法:
    ここに画像の説明を挿入します

C++ コード

#include <bits/stdc++.h>
using namespace std;

using ll = long long;
const ll mod = 1000000007;

class Solution {
    
    
public:
    int keyboard(int k, int n) {
    
    
        vector<vector<ll>> dp(n + 1, vector<ll>(27, 0L));
        for (int j = 0; j <= 26; ++j) {
    
    
            dp[0][j] = 1;
        }
        for (int i = 1; i <= n; ++i) {
    
    
            for (int j = 1; j <= 26; ++j) {
    
    
                for (int x = 0; x <= k; ++x) {
    
    
                    if (i >= x) {
    
    
                        dp[i][j] += dp[i - x][j - 1] * C(i, x);
                    }
                }
                dp[i][j] %= mod;
                // cout << i << "," << j << ":" << dp[i][j] << endl;
            }
        }
        return dp[n][26];
    }
    
    ll C(int n, int m)
    {
    
    
        ll fz = 1;
        ll fm = 1;
        for (int i = n; i >= n - m + 1; --i) {
    
    
            fz *= i;
        }
        for (int j = m; j >= 2; --j) {
    
    
            fm *= j;
        }
        return fz / fm;
    }
};

おすすめ

転載: blog.csdn.net/weixin_36313227/article/details/126794462