I. Modulo Permutations
题目传送门:
题目大意:
给你一个自然数
n
n
n,问你
1
1
1到
n
n
n这几个数字能排出多少个排列方式使得排列满足:
后面那半句的意思就是所谓的排列是个环形的。
思路:
最终序列并不是递减的,而是如图最右边角落那个小环一样的状态。
代码:
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int maxn = 1e6 + 10;
const int mod = 1e9 + 7;
ll dp[maxn];
int main() {
int n;
scanf("%d", &n);
if (n <= 2) {
printf("%lld\n", n);
return 0;
}
// if (n == 3) {
// printf("6\n");
// return 0;
// }
dp[n] = 1;
for (int i = n - 1; i >= 4; i--) {
dp[i] = 1;
for (int j = i - 1; j <= n; j += (i - 1)) {
for (int k = 0; k <= 2; k++) {
if (k + j <= i) continue;
dp[i] += dp[j + k];
dp[i] %= mod;
}
}
}
dp[3] = 1;
for (int i = 4; i <= n; i++) {
dp[3] += dp[i];
dp[3] %= mod;
}
ll ans = (dp[3] * 2) * n % mod;
//dp[2]=dp[3]+dp[4]+...=dp[3]*2;
printf("%lld\n", ans);
}
关于我问为什么dp[2]不用++,因为本身就只有一种情况,后面不跟东西,所以不用。
大概意思就是拼起来的时候会重复算。