// Marcin Knapik Potyczki Algorytmiczne, dzień 2, Zadanie "Desant"[A] // złożoność O(2^n) #pragma GCC optimize("O3") //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") #pragma GCC optimize("Ofast") #pragma GCC optimize("unroll-loops") #include<bits/stdc++.h> using namespace std; #define rall(s) s.rbegin(), s.rend() #define f first #define s second #define ll long long #define pb push_back #define FOR(i, s) for(int i = 0; i < s; i++) #define sz(s) (int)s.size() int q, n; int tab[50]; int mini[50]; int ile[50]; int pozycje[50]; int typy[50]; int siz = 0; int ile_zle = 0; int kon_rozmiar; void backtrack(int temp){ if(temp == 0){ if(ile_zle == mini[siz]) ile[siz]++; return; } int start = 0; if(siz) start = typy[siz-1]+1; for(int i = start; i < n - temp + 1; i++){ int teraz_zle = 0; for(int j = 0; j < siz; j++) teraz_zle += (tab[typy[j]] > tab[i]); if(teraz_zle + ile_zle < mini[siz+1]){ mini[siz+1] = teraz_zle + ile_zle; ile[siz+1] = 0; } if(teraz_zle + ile_zle <= mini[kon_rozmiar]){ typy[siz] = i; siz++; ile_zle += teraz_zle; backtrack(temp-1); ile_zle -= teraz_zle; siz--; } } } void solve(){ cin >> n; FOR(i, n) cin >> tab[i]; for(int i = 0; i < 50; i++) mini[i] = 100000000; if(n <= 24){ for(int i = 1; i < (1<<n); i++){ int zle = 0; int temp = 0; for(int j = 0; j < n; j++) if(i & (1<<j)) pozycje[temp++] = j; for(int j = 0; j < temp; j++) for(int J = j+1; J < temp; J++) zle += (tab[pozycje[j]] > tab[pozycje[J]]); if(zle < mini[temp]){ ile[temp] = 1; mini[temp] = zle; } else if(zle == mini[temp]) ile[temp]++; } } else{ for(int i = n; i >= 1; i--){ kon_rozmiar = i; backtrack(i); } } for(int i = 1; i <= n; i++) cout << mini[i] << ' ' << ile[i] << '\n'; } int main(){ ios::sync_with_stdio(0); cin.tie(0); solve(); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | // Marcin Knapik Potyczki Algorytmiczne, dzień 2, Zadanie "Desant"[A] // złożoność O(2^n) #pragma GCC optimize("O3") //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") #pragma GCC optimize("Ofast") #pragma GCC optimize("unroll-loops") #include<bits/stdc++.h> using namespace std; #define rall(s) s.rbegin(), s.rend() #define f first #define s second #define ll long long #define pb push_back #define FOR(i, s) for(int i = 0; i < s; i++) #define sz(s) (int)s.size() int q, n; int tab[50]; int mini[50]; int ile[50]; int pozycje[50]; int typy[50]; int siz = 0; int ile_zle = 0; int kon_rozmiar; void backtrack(int temp){ if(temp == 0){ if(ile_zle == mini[siz]) ile[siz]++; return; } int start = 0; if(siz) start = typy[siz-1]+1; for(int i = start; i < n - temp + 1; i++){ int teraz_zle = 0; for(int j = 0; j < siz; j++) teraz_zle += (tab[typy[j]] > tab[i]); if(teraz_zle + ile_zle < mini[siz+1]){ mini[siz+1] = teraz_zle + ile_zle; ile[siz+1] = 0; } if(teraz_zle + ile_zle <= mini[kon_rozmiar]){ typy[siz] = i; siz++; ile_zle += teraz_zle; backtrack(temp-1); ile_zle -= teraz_zle; siz--; } } } void solve(){ cin >> n; FOR(i, n) cin >> tab[i]; for(int i = 0; i < 50; i++) mini[i] = 100000000; if(n <= 24){ for(int i = 1; i < (1<<n); i++){ int zle = 0; int temp = 0; for(int j = 0; j < n; j++) if(i & (1<<j)) pozycje[temp++] = j; for(int j = 0; j < temp; j++) for(int J = j+1; J < temp; J++) zle += (tab[pozycje[j]] > tab[pozycje[J]]); if(zle < mini[temp]){ ile[temp] = 1; mini[temp] = zle; } else if(zle == mini[temp]) ile[temp]++; } } else{ for(int i = n; i >= 1; i--){ kon_rozmiar = i; backtrack(i); } } for(int i = 1; i <= n; i++) cout << mini[i] << ' ' << ile[i] << '\n'; } int main(){ ios::sync_with_stdio(0); cin.tie(0); solve(); } |