diff --git "a/lcp/LCP 25. \345\217\244\350\221\243\351\224\256\347\233\230/README.md" "b/lcp/LCP 25. \345\217\244\350\221\243\351\224\256\347\233\230/README.md" index 60bb4355d3abf..0fc09493e32f4 100644 --- "a/lcp/LCP 25. \345\217\244\350\221\243\351\224\256\347\233\230/README.md" +++ "b/lcp/LCP 25. \345\217\244\350\221\243\351\224\256\347\233\230/README.md" @@ -42,4 +42,159 @@ edit_url: https://github.com/doocs/leetcode/edit/main/lcp/LCP%2025.%20%E5%8F%A4% +### 方法一:动态规划 + +我们定义 $f[i][j]$ 表示按了 $i$ 次按键,且使用了前 $j$ 个字母的方案数。初始时 $f[0]$ 全部为 $1$,表示没有按键时只有一种方案,其余 $f[i][j] = 0$。 + +对于 $f[i][j]$,我们考虑其转移方式。我们可以枚举第 $j$ 个字母一共使用了多少次,设为 $h$,其中 $0 \leq h \leq \min(i, k)$,那么我们可以从 $f[i - h][j - 1]$ 转移过来,且第 $j$ 个字母可以在 $i$ 次按键中使用 $h$ 次,方案数为 $\binom{i}{h}$。即: + +$$ +f[i][j] = \sum_{h = 0}^{\min(i, k)} f[i - h][j - 1] \cdot \binom{i}{h} +$$ + +最终答案即为 $f[n][26]$。 + +时间复杂度 $O(n \times k \times |\Sigma|)$,空间复杂度 $O(n \times |\Sigma|)$。其中 $|\Sigma|$ 表示字母表大小。 + + + +#### Python3 + +```python +class Solution: + def keyboard(self, k: int, n: int) -> int: + f = [[0] * 27 for _ in range(n + 1)] + f[0] = [1] * 27 + mod = 10**9 + 7 + for i in range(1, n + 1): + for j in range(1, 27): + for h in range(min(k, i) + 1): + f[i][j] += f[i - h][j - 1] * comb(i, h) + f[i][j] %= mod + return f[n][26] +``` + +#### Java + +```java +class Solution { + public int keyboard(int k, int n) { + int[][] c = new int[n + 1][k + 1]; + for (int i = 0; i <= n; ++i) { + c[i][0] = 1; + } + final int mod = (int) 1e9 + 7; + for (int i = 1; i <= n; ++i) { + for (int j = 1; j <= k; ++j) { + c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod; + } + } + int[][] f = new int[n + 1][27]; + Arrays.fill(f[0], 1); + for (int i = 1; i <= n; ++i) { + for (int j = 1; j < 27; ++j) { + for (int h = 0; h <= Math.min(i, k); ++h) { + f[i][j] = (f[i][j] + (int) ((long) f[i - h][j - 1] * c[i][h] % mod)) % mod; + } + } + } + return f[n][26]; + } +} +``` + +#### C++ + +```cpp +class Solution { +public: + int keyboard(int k, int n) { + int f[n + 1][27]; + memset(f, 0, sizeof(f)); + for (int j = 0; j < 27; ++j) { + f[0][j] = 1; + } + int c[n + 1][k + 1]; + memset(c, 0, sizeof(c)); + c[0][0] = 1; + const int mod = 1e9 + 7; + for (int i = 1; i <= n; ++i) { + c[i][0] = 1; + for (int j = 1; j <= k; ++j) { + c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod; + } + } + for (int i = 1; i <= n; ++i) { + for (int j = 1; j < 27; ++j) { + for (int h = 0; h <= min(i, k); ++h) { + f[i][j] = (f[i][j] + 1LL * f[i - h][j - 1] * c[i][h] % mod) % mod; + } + } + } + return f[n][26]; + } +}; +``` + +#### Go + +```go +func keyboard(k int, n int) int { + c := make([][]int, n+1) + for i := range c { + c[i] = make([]int, k+1) + c[i][0] = 1 + } + const mod int = 1e9 + 7 + for i := 1; i <= n; i++ { + for j := 1; j <= k; j++ { + c[i][j] = (c[i-1][j-1] + c[i-1][j]) % mod + } + } + f := make([][27]int, n+1) + for j := range f[0] { + f[0][j] = 1 + } + for i := 1; i <= n; i++ { + for j := 1; j < 27; j++ { + for h := 0; h <= min(i, k); h++ { + f[i][j] = (f[i][j] + f[i-h][j-1]*c[i][h]%mod) % mod + } + } + } + return f[n][26] +} +``` + +#### TypeScript + +```ts +function keyboard(k: number, n: number): number { + const c: number[][] = Array.from({ length: n + 1 }, () => Array(k + 1).fill(0)); + c[0][0] = 1; + const mod = 10 ** 9 + 7; + for (let i = 1; i <= n; ++i) { + c[i][0] = 1; + for (let j = 1; j <= k; ++j) { + c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod; + } + } + const f: number[][] = Array.from({ length: n + 1 }, () => Array(27).fill(0)); + f[0].fill(1); + for (let i = 1; i <= n; ++i) { + for (let j = 1; j < 27; ++j) { + for (let h = 0; h <= Math.min(i, k); ++h) { + const v = Number((BigInt(f[i - h][j - 1]) * BigInt(c[i][h])) % BigInt(mod)); + f[i][j] = (f[i][j] + v) % mod; + } + } + } + return f[n][26]; +} +``` + + + + + diff --git "a/lcp/LCP 25. \345\217\244\350\221\243\351\224\256\347\233\230/Solution.cpp" "b/lcp/LCP 25. \345\217\244\350\221\243\351\224\256\347\233\230/Solution.cpp" new file mode 100644 index 0000000000000..9734f07d85e29 --- /dev/null +++ "b/lcp/LCP 25. \345\217\244\350\221\243\351\224\256\347\233\230/Solution.cpp" @@ -0,0 +1,28 @@ +class Solution { +public: + int keyboard(int k, int n) { + int f[n + 1][27]; + memset(f, 0, sizeof(f)); + for (int j = 0; j < 27; ++j) { + f[0][j] = 1; + } + int c[n + 1][k + 1]; + memset(c, 0, sizeof(c)); + c[0][0] = 1; + const int mod = 1e9 + 7; + for (int i = 1; i <= n; ++i) { + c[i][0] = 1; + for (int j = 1; j <= k; ++j) { + c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod; + } + } + for (int i = 1; i <= n; ++i) { + for (int j = 1; j < 27; ++j) { + for (int h = 0; h <= min(i, k); ++h) { + f[i][j] = (f[i][j] + 1LL * f[i - h][j - 1] * c[i][h] % mod) % mod; + } + } + } + return f[n][26]; + } +}; diff --git "a/lcp/LCP 25. \345\217\244\350\221\243\351\224\256\347\233\230/Solution.go" "b/lcp/LCP 25. \345\217\244\350\221\243\351\224\256\347\233\230/Solution.go" new file mode 100644 index 0000000000000..dee58ef44f2c6 --- /dev/null +++ "b/lcp/LCP 25. \345\217\244\350\221\243\351\224\256\347\233\230/Solution.go" @@ -0,0 +1,25 @@ +func keyboard(k int, n int) int { + c := make([][]int, n+1) + for i := range c { + c[i] = make([]int, k+1) + c[i][0] = 1 + } + const mod int = 1e9 + 7 + for i := 1; i <= n; i++ { + for j := 1; j <= k; j++ { + c[i][j] = (c[i-1][j-1] + c[i-1][j]) % mod + } + } + f := make([][27]int, n+1) + for j := range f[0] { + f[0][j] = 1 + } + for i := 1; i <= n; i++ { + for j := 1; j < 27; j++ { + for h := 0; h <= min(i, k); h++ { + f[i][j] = (f[i][j] + f[i-h][j-1]*c[i][h]%mod) % mod + } + } + } + return f[n][26] +} diff --git "a/lcp/LCP 25. \345\217\244\350\221\243\351\224\256\347\233\230/Solution.java" "b/lcp/LCP 25. \345\217\244\350\221\243\351\224\256\347\233\230/Solution.java" new file mode 100644 index 0000000000000..1903e74abd965 --- /dev/null +++ "b/lcp/LCP 25. \345\217\244\350\221\243\351\224\256\347\233\230/Solution.java" @@ -0,0 +1,24 @@ +class Solution { + public int keyboard(int k, int n) { + int[][] c = new int[n + 1][k + 1]; + for (int i = 0; i <= n; ++i) { + c[i][0] = 1; + } + final int mod = (int) 1e9 + 7; + for (int i = 1; i <= n; ++i) { + for (int j = 1; j <= k; ++j) { + c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod; + } + } + int[][] f = new int[n + 1][27]; + Arrays.fill(f[0], 1); + for (int i = 1; i <= n; ++i) { + for (int j = 1; j < 27; ++j) { + for (int h = 0; h <= Math.min(i, k); ++h) { + f[i][j] = (f[i][j] + (int) ((long) f[i - h][j - 1] * c[i][h] % mod)) % mod; + } + } + } + return f[n][26]; + } +} diff --git "a/lcp/LCP 25. \345\217\244\350\221\243\351\224\256\347\233\230/Solution.py" "b/lcp/LCP 25. \345\217\244\350\221\243\351\224\256\347\233\230/Solution.py" new file mode 100644 index 0000000000000..f9de2c71c8aa0 --- /dev/null +++ "b/lcp/LCP 25. \345\217\244\350\221\243\351\224\256\347\233\230/Solution.py" @@ -0,0 +1,11 @@ +class Solution: + def keyboard(self, k: int, n: int) -> int: + f = [[0] * 27 for _ in range(n + 1)] + f[0] = [1] * 27 + mod = 10**9 + 7 + for i in range(1, n + 1): + for j in range(1, 27): + for h in range(min(k, i) + 1): + f[i][j] += f[i - h][j - 1] * comb(i, h) + f[i][j] %= mod + return f[n][26] diff --git "a/lcp/LCP 25. \345\217\244\350\221\243\351\224\256\347\233\230/Solution.ts" "b/lcp/LCP 25. \345\217\244\350\221\243\351\224\256\347\233\230/Solution.ts" new file mode 100644 index 0000000000000..11cdc8602a219 --- /dev/null +++ "b/lcp/LCP 25. \345\217\244\350\221\243\351\224\256\347\233\230/Solution.ts" @@ -0,0 +1,22 @@ +function keyboard(k: number, n: number): number { + const c: number[][] = Array.from({ length: n + 1 }, () => Array(k + 1).fill(0)); + c[0][0] = 1; + const mod = 10 ** 9 + 7; + for (let i = 1; i <= n; ++i) { + c[i][0] = 1; + for (let j = 1; j <= k; ++j) { + c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod; + } + } + const f: number[][] = Array.from({ length: n + 1 }, () => Array(27).fill(0)); + f[0].fill(1); + for (let i = 1; i <= n; ++i) { + for (let j = 1; j < 27; ++j) { + for (let h = 0; h <= Math.min(i, k); ++h) { + const v = Number((BigInt(f[i - h][j - 1]) * BigInt(c[i][h])) % BigInt(mod)); + f[i][j] = (f[i][j] + v) % mod; + } + } + } + return f[n][26]; +}