题目链接:置置置换
令 dp[i] 为前 i 个数的排列的方案数。
因为是一个排列,所以相对大小都是固定的。
1 2 3 的方案数和 1 3 7 的方案数一样。
所以我们枚举当前数字 i 加入到前面每个奇数位置 j 当中,从 i - 1 个数字当中选 j -1 个数字,然后再乘数字的方案数。
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e3+10,mod=1e9+7;
int n,dp[N],f[N],inv[N];
int qmi(int a,int b=mod-2){int s=1;for(;b;b>>=1,a=a*a%mod) if(b&1) s=s*a%mod;return s;
}
inline int C(int n,int m){return f[n]*inv[m]%mod*inv[n-m]%mod;}
signed main(){cin>>n; f[0]=1;for(int i=1;i<=n;i++) f[i]=f[i-1]*i%mod;inv[n]=qmi(f[n]);for(int i=n-1;i>=0;i--) inv[i]=inv[i+1]*(i+1)%mod;dp[0]=1,dp[1]=1,dp[2]=1;for(int i=3;i<=n;i++){for(int j=1;j<=i;j+=2){dp[i]=(dp[i]+C(i-1,j-1)*dp[j-1]%mod*dp[i-j])%mod;}}cout<<dp[n];return 0;
}