题解:CF316D3 PE Lesson

题面


这题怎么可能只有 2400 啊?


容易发现答案只与 \(a_i=1,a_i=2\)\(i\) 的数量有关,我们考虑分别将其记为 \(a1,a2\)

考虑最终结果的排列满足什么性质,手玩一下可以发现这些排列中每一个环内最多只有两个数 \(a_i=1\)

先考虑给所有 \(a1\)\(a_i=1\) 的点的分组情况,每个点可以独自成一组,也可以和另一个在一个环里,即有 \(f_i=f_{i-1}+(i-1)\times f_{i-2}\)。表示第 \(i\) 个点独立或是与前 \(i-1\) 个点中的某一个在一起。

接下来考虑将剩的 \(a2\) 个点插到环里去,结合第一类斯特林数的递推方法,对于第 \(i\) 个点,有 \(1+(a1+i-1)\) 种选择,代表自成一环或跟在前面某一个点后边。

所以总方案数为 \(f_{a1}\times \prod\limits_{i=a1+1}^ni\)


代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod=1e9+7;
int n,a1,a2,a[1000005],dp[1000005];
signed main()
{
	scanf("%lld",&n);
	for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
	for(int i=1;i<=n;i++)if(a[i]==1)a1++;else a2++;
	dp[0]=dp[1]=1;
	for(int i=1;i<=a1;i++)dp[i]=(dp[i-1]+(i-1)*dp[i-2])%mod;
	for(int i=n;i>=n-a2+1;i--)dp[a1]=dp[a1]*i%mod;
	printf("%lld",dp[a1]);
	return 0;
}
posted @ 2024-12-03 19:55  Grisses  阅读(8)  评论(0)    收藏  举报
Document