[笔记]自己想的一个题,解题思路以及代码

自己在学校想到的,很大概率是已经存在的原题,不过这道题很有趣,所以记录一下

题意简述

输入一个\(N\),询问\(\{1,2,…,N\}\)的所有全排列中满足下列条件的排列\(P\)的个数取模\(998244353\)的值:

  • 定义\(A\)数组,初始全为空。对于\(1\leq i\leq N\),设\(A_{P_i}\)\(i\)。如果\(A=P\),则满足条件。

说明:\(1\leq N \leq 10^7\)

样例及解释

Input: 3
Output: 4

\(\{1,2,3\}\)的全排列有\(\{1,2,3\},\{1,3,2\},\{2,1,3\},\{2,3,1\},\{3,1,2\},\{3,2,1\}\)

依照规则填写的\(A\)分别是\(\{1,2,3\},\{1,3,2\},\{2,1,3\},\textcolor{red}{\{3,1,2\}},\textcolor{red}{\{2,3,1\}},\{3,2,1\}\)

红色的是不匹配的,于是答案为\(4\)

解题思路

根据题意,满足条件必须要求\(A_i=P_i,A_{P_i}=i\)

\(A_i=P_i\)\(A_{P_i}=P_{P_i}\)

又因为\(A_{P_i}=i\),所以\(P_{P_i}=i\)


满足\(P_{P_i}=i\)\(P\)即为符合条件,接下来我们用dp解决。

\(dp_i\)\(N=i\)时的答案,初始\(dp_1=1,dp_2=2\)

递推式:\(dp_i=dp_{i-1}+(i-1)*dp_{i-2}\)

怎么推导的呢?我画个图,通过\(N=4\)的情况解释:

下面附上代码实现↓

Code

可以用滚动数组优化空间。(懒)

#include<bits/stdc++.h>
#define int long long
#define mod 998244353
using namespace std;
int n,dp[10000010];
signed main(){
	cin>>n;
	dp[1]=1,dp[2]=2;
	for(int i=3;i<=n;i++){
		dp[i]=(dp[i-1]+((i-1)*dp[i-2])%mod)%mod;
	}
	cout<<dp[n];
	return 0;
}

\[[THE\ \ END] \]

注:若发现错误或改进建议,请在评论区指出,感谢万分!

posted @ 2024-03-06 00:41  Sinktank  阅读(14)  评论(0编辑  收藏  举报
★CLICK FOR MORE INFO★ TOP-BOTTOM-THEME
Enable/Disable Transition
Copyright © 2023 ~ 2024 Sinktank - 1328312655@qq.com
Illustration from 稲葉曇『リレイアウター/Relayouter/中继输出者』,by ぬくぬくにぎりめし.