C 答题卡
题目地址:
基本思路:
开始没有思路的话可以先dfs暴力打个表看看,打表代码如下:
#pragma GCC optimize(2) #pragma GCC optimize(3) #include <bits/stdc++.h> using namespace std; #define IO std::ios::sync_with_stdio(false) #define int long long #define rep(i, l, r) for (int i = l; i <= r; i++) #define per(i, l, r) for (int i = l; i >= r; i--) #define mset(s, _) memset(s, _, sizeof(s)) #define pb push_back #define pii pair <int, int> #define mp(a, b) make_pair(a, b) #define INF 0x3f3f3f3f const int maxn = 1e5 + 10; const int mod = 1e9 + 7; int n,ans = 0; bool vis[maxn]; void dfs(int s){ if(s == n + 1){ ans++; ans %= mod; return; } if(vis[s]) dfs(s + 1); else{ for(int i = s ; i <= n ; i++){ if(!vis[i]){ vis[i] = true; dfs(s + 1); vis[i] = false; } } } } signed main() { IO; rep(i,1,15){ n = i; ans = 0; mset(vis,false); dfs(1); cout << ans % mod << '\n'; } return 0; }
我们交上去看一下得了50分,说明打的表是对的,这时候如果我们直接硬推递推式也是可以的,但是我们还是看一下正确的思考方向。
我们考虑如果第一行选择第一列,那么余下来的就是一个的矩阵没有确定,如果第一行选择其余的列,那么我们思考一下,由于对称关系还有一行的选择就也确定了,这时候就有余下的的矩阵没有确定,那么我们以表示的矩阵的结果,那么我们就能得到这样的递推式。
和打表结果比对一下没有问题,说明思路是对的。
参考代码:
#pragma GCC optimize(2) #pragma GCC optimize(3) #include <bits/stdc++.h> using namespace std; #define IO std::ios::sync_with_stdio(false) #define int long long #define rep(i, l, r) for (int i = l; i <= r; i++) #define per(i, l, r) for (int i = l; i >= r; i--) #define mset(s, _) memset(s, _, sizeof(s)) #define pb push_back #define pii pair <int, int> #define mp(a, b) make_pair(a, b) #define INF 0x3f3f3f3f const int maxn = 1e5 + 10; const int mod = 1e9 + 7; int n,f[maxn]; signed main(){ IO; cin >> n; f[0] = f[1] = 1; f[2] = 2; rep(i,3,n) f[i] = ( f[i-1] + (i-1) * f[i-2] % mod ) % mod; cout << f[n] % mod << '\n'; return 0; }