1. 程式人生 > >ACM-ICPC 2018 徐州賽區現場賽 I. Rikka with Sorting Networks (思維+DFS)

ACM-ICPC 2018 徐州賽區現場賽 I. Rikka with Sorting Networks (思維+DFS)

題目連結:https://codeforces.com/gym/102012/problem/I

題意:問有多少個 1 到 n 的排列,使得用給定的 k 個比較器(使 au 和 av 有序)排序後,整個序列的最長上升子序列為 n - 1。

題解:先處理出全部最長上升子序列為 n - 1 的排列,然後列舉每個比較器使用與否,計數即可。(注意卡常)

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define
ull unsigned long long 5 #define mst(a,b) memset((a),(b),sizeof(a)) 6 #define mp(a,b) make_pair(a,b) 7 #define pi acos(-1) 8 #define pii pair<int,int> 9 #define pb push_back 10 const int INF = 0x3f3f3f3f; 11 const double eps = 1e-6; 12 const int maxn = 1e6 + 10; 13 const int maxm = 1e5 + 10;
14 //const ll mod = 998244353; 15 16 set<vector<int>>se; 17 int a[55],u[15],v[15]; 18 19 int dfs(vector<int>&vec,int now) { 20 if(now < 0) return 1; 21 int l = u[now], r = v[now], ans = 0; 22 if(vec[l] < vec[r]) { 23 ans += dfs(vec,now - 1); 24 swap(vec[l],vec[r]);
25 ans += dfs(vec,now - 1); 26 swap(vec[l],vec[r]); 27 } 28 return ans; 29 } 30 31 int main() { 32 #ifdef local 33 freopen("data.txt", "r", stdin); 34 // freopen("data.txt", "w", stdout); 35 #endif 36 for(int i = 0; i < 55; i++) a[i] = i; 37 int t; 38 scanf("%d",&t); 39 while(t--) { 40 se.clear(); 41 int n,k,mod; 42 scanf("%d%d%d",&n,&k,&mod); 43 for(int i = 0; i < k; i++) { 44 scanf("%d%d",&u[i],&v[i]); 45 u[i]--, v[i]--; 46 } 47 int ans = 0; 48 for(int i = 0; i < n; i++) { 49 vector<int>vec; 50 for(int j = 0; j < i; j++) vec.push_back(j); 51 for(int j = i + 1; j < n; j++) vec.push_back(j); 52 for(int j = 0; j < n; j++) { 53 vector<int>v; 54 for(int k = 0; k < j; k++) v.push_back(vec[k]); 55 v.push_back(i); 56 for(int k = j; k < vec.size(); k++) v.push_back(vec[k]); 57 if(se.find(v) == se.end()) ans += dfs(v,k - 1); 58 se.insert(v); 59 } 60 } 61 printf("%d\n",ans % mod); 62 } 63 return 0; 64 }