class Solution {
public:
int rearrangeSticks(int n, int k) {
}
};
1866. 恰有 K 根木棍可以看到的排列数目
有 n
根长度互不相同的木棍,长度为从 1
到 n
的整数。请你将这些木棍排成一排,并满足从左侧 可以看到 恰好 k
根木棍。从左侧 可以看到 木棍的前提是这个木棍的 左侧 不存在比它 更长的 木棍。
[1,3,2,5,4]
,那么从左侧可以看到的就是长度分别为 1
、3
、5
的木棍。给你 n
和 k
,返回符合题目要求的排列 数目 。由于答案可能很大,请返回对 109 + 7
取余 的结果。
示例 1:
输入:n = 3, k = 2 输出:3 解释:[1,3,2], [2,3,1] 和 [2,1,3] 是仅有的能满足恰好 2 根木棍可以看到的排列。 可以看到的木棍已经用粗体+斜体标识。
示例 2:
输入:n = 5, k = 5 输出:1 解释:[1,2,3,4,5] 是唯一一种能满足全部 5 根木棍可以看到的排列。 可以看到的木棍已经用粗体+斜体标识。
示例 3:
输入:n = 20, k = 11 输出:647427950 解释:总共有 647427950 (mod 109 + 7) 种能满足恰好有 11 根木棍可以看到的排列。
提示:
1 <= n <= 1000
1 <= k <= n
原站题解
java 解法, 执行用时: 48 ms, 内存消耗: 53.5 MB, 提交时间: 2023-09-21 10:40:17
class Solution { int N = 1010; int MOD = 1000000007; int[][] f = new int[N][N]; public int rearrangeSticks(int n, int k) { f[0][0] = 1; for (int i = 1; i <= n; i ++ ) for (int j = 1; j <= k; j ++ ) f[i][j] = (int)((f[i - 1][j - 1] + (long)(i - 1) * (f[i - 1][j])) % MOD); return f[n][k]; } }
python3 解法, 执行用时: 1624 ms, 内存消耗: 16 MB, 提交时间: 2023-09-21 10:39:12
class Solution: def rearrangeSticks(self, n: int, k: int) -> int: mod = 10**9 + 7 f = [1] + [0] * k for i in range(1, n + 1): g = [0] * (k + 1) for j in range(1, k + 1): g[j] = (f[j] * (i - 1) + f[j - 1]) % mod f = g return f[k]
cpp 解法, 执行用时: 116 ms, 内存消耗: 61.8 MB, 提交时间: 2023-09-21 10:39:04
class Solution { private: static constexpr int mod = 1000000007; public: int rearrangeSticks(int n, int k) { vector<int> f(k + 1); f[0] = 1; for (int i = 1; i <= n; ++i) { vector<int> g(k + 1); for (int j = 1; j <= k; ++j) { g[j] = ((long long)f[j] * (i - 1) % mod + f[j - 1]) % mod; } f = move(g); } return f[k]; } };
golang 解法, 执行用时: 4 ms, 内存消耗: 8.5 MB, 提交时间: 2023-09-21 10:37:57
/** * 原问题本质上就是在问长为 n 的排列划分成 k 个非空圆排列的方案数,这就是第一类斯特林数。 */ var f [1001][1001]int func init() { f[0][0] = 1 for i := 1; i <= 1000; i++ { for j := 1; j <= i; j++ { f[i][j] = (f[i-1][j-1] + (i-1)*f[i-1][j]) % (1e9 + 7) } } } func rearrangeSticks(n, k int) int { return f[n][k] }