Problem:
Problem I:
Sort by Hand
It's time to arrange the books on your bookshelf. There are
n
books in the shelf and each book has a unique number; you want to sort the books according to the numbers. You know that the quick sort and the merge sort are fast sorting methods, but it is too hard for you to simulate them by hand - they are efficient for computers, but not for humans. Thus, you decided to sort the books by inserting the book with the number
i
into the
i
-th position. How many insertions are required to complete this task?
Input
The first line of the input is
n
(1 ≤
n
≤ 20), which is the number of books. The second line contains
n
integers
v
1
, ... ,
v
n
(1 ≤
v
i
≤
n
), where
v
i
indicates the number of the book at the
i
-th position before the sorting. All
v
i
's are distinct.
Output
Print the minimum number of insertions in a line. If it is impossible for him to complete the sort, print "impossible" (without quotes).
Sample Input 1
3
1 2 3
Output for the Sample Input 1
0
Sample Input 2
3
2 1 3
Output for the Sample Input 2
1
Sample Input 3
3
3 2 1
Output for the Sample Input 3
2
Sample Input 4
20
4 14 11 13 17 10 1 12 2 6 16 15 8 7 19 18 3 5 9 20
Output for the Sample Input 4
14

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
#define REP(i,n) for(int i=0; i<(int)(n); ++i)

using namespace std;

int greedy1(vector<int> v) {
    int res = 0;
    for(int i = 0; i < v.size(); i++) {
        int e = i;
        while(v[e] != i) e++;
        if(e > i) {
            res++;
        }
        while(e > i) {
            swap(v[e - 1], v[e]);
            e--;
        }
    }
    return res;
}
int greedy2(vector<int> v) {
    int res = 0;
    for(int i = v.size() - 1; i >= 0; i--) {
        int b = i;
        while(v[b] != i) b--;
        if(b < i) {
            res++;
        }
        while(b < i) {
            swap(v[b], v[b + 1]);
            b++;
        }
    }
    return res;
}
int greedy3(const vector<int>& v) {
    int n = v.size();
    int dp[22][22] = {};
    REP(i, n + 1) REP(j, n + 1) dp[i][j] = INT_MAX;
    dp[0][n] = 0;
    for(int t = n; t > 0; t--) {
        for(int l = 0; l + t <= n; l++) {
            int r = l + t;
            vector<int> a;
            for(int i = 0; i < n; i++) {
                if(l <= v[i] && v[i] < r) {
                    a.push_back(v[i]);
                }
            }
            int first = a[0];
            int last = a.back();
            dp[l + 1][r] = min(dp[l + 1][r], dp[l][r] + (first == l ? 0 : 1));
            dp[l][r - 1] = min(dp[l][r - 1], dp[l][r] + (last == r - 1 ? 0 : 1));
        }
    }
    int res = INT_MAX;
    for(int l = 0; l < n; l++) {
        res = min(res, dp[l][l]);
    }
    return res;
}

struct State{
    int c, h;
    vector<int> v;
    State(int c_, const vector<int>& v_) : c(c_), v(v_.begin(), v_.end()) {
        h = greedy3(v);
    }
    bool operator < (const State& s) const {
        return c + h > s.c + s.h; // reversed
    }
};


int main(){
    int n;
    while(cin >> n){
        vector<int> init(n);
        REP(i, n) cin >> init[i];
        REP(i, n) init[i]--;
        // cout << greedy1(v) << endl;
        // cout << greedy2(v) << endl;
        // cout << greedy3(v) << endl;
        priority_queue<State> que;
        set< vector<int> > used;
        que.push(State(0, init));
        used.insert(init);
        while(!que.empty()){
            const State s = que.top(); que.pop();
            if(s.h == 0) {
                cout << s.c << endl;
                break;
            }
            for(int i = 0; i < n; i++) {
                if(s.v[i] != i) {
                    vector<int> nv = s.v;
                    int j;
                    assert(nv.size() == n);
                    for(j = 0; j < n; j++) if(nv[j] == i) break;
                    if(i < j) {
                        while(j > i) {
                            swap(nv[j - 1], nv[j]);
                            j--;
                        }
                    } else {
                        while(j < i) {
                            swap(nv[j], nv[j + 1]);
                            j++;
                        }
                    }
                    if(!used.count(nv)) {
                        used.insert(nv);
                        que.push(State(s.c + 1, nv));
                    }
                }
            }
        }
    }
    return 0;
}
accuracy: 0.18181818181818182
time_ms: 50
memory_kb: 1524
final_rank: 4

code_snippet: #include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>

using namespace std;

#define FOR(i,k,n) for(int i=(k); i<(int)(n); ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)

template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cerr<<*i<<" "; cerr<<endl; }
inline bool valid(int x, int y, int W, int H){ return (x >= 0 && y >= 0 && x < W && y < H); }

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
int N;
int v[20];
int memo[1 << 20];
int dfs(int S){
  int& res = memo[S];
  if(res != -1) return res;
  res = INF;
  int cur = -1;
  bool sorted = true;
  for(int i = 0; i < N; i++) if(0 == (S >> i & 1)) {
    if(cur > v[i]) sorted = false;
    cur = v[i];
  }
  if(sorted) return 0;
  for(int i = 0; i < N; i++) if(0 == (S >> i & 1)) {
    res = min(res, 1 + dfs(S | (1 << i)));
  }
  return res;
}

int main(){
  while(cin >> N){
    REP(i, N) cin >> v[i];
    memset(memo, -1, sizeof(memo));
    int ans = dfs(0);
    assert(ans != INF);
    cout << ans << endl;
  }
  return 0;
}
accuracy: 0.21212121212121213
time_ms: 110
memory_kb: 5264
final_rank: 1

code_snippet: #include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>

using namespace std;

#define FOR(i,k,n) for(int i=(k); i<(int)(n); ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)

template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cerr<<*i<<" "; cerr<<endl; }
inline bool valid(int x, int y, int W, int H){ return (x >= 0 && y >= 0 && x < W && y < H); }

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
int N;
int v[20];
int memo[1 << 20];
int dfs(int S){
  int& res = memo[S];
  if(res != -1) return res;
  res = INF;
  int cur = -1;
  bool sorted = true;
  for(int i = 0; i < N; i++) if(0 == (S >> i & 1)) {
    if(cur > v[i]) sorted = false;
    cur = v[i];
  }
  if(sorted) return 0;
  for(int i = 0; i < N; i++) if(0 == (S >> i & 1)) {
    res = min(res, 1 + dfs(S | (1 << i)));
  }
  return res;
}

int main(){
  while(cin >> N){
    REP(i, N) cin >> v[i];
    memset(memo, -1, sizeof(memo));
    cout << dfs(0) << endl;
  }
  return 0;
}
accuracy: 0.21212121212121213
time_ms: 110
memory_kb: 5264
final_rank: 1

code_snippet: #include <cstdlib>
#include <climits>
#include <cstring>
#define REP(i,n) for(int i=0; i<(int)(n); i++)

#include <set>
#include <cstdio>
inline int getInt(){ int s; scanf("%d", &s); return s; }

using namespace std;

int a[20];
int n;
int dp[1 << 20];

int solve(int f){
  if(f == ((1 << n) - 1)) return 0;
  if(dp[f] != -1) return dp[f];

  int ff = f;
  int ret = INT_MAX;

  REP(i,n) if((f & (1 << i)) == 0){
    for(int j = 0; j < i; j++)
      if(a[j] > a[i] && ((f & (1 << j)) == 0))
        goto next;
    for(int j = i + 1; j < n; j++)
      if(a[j] < a[i] && ((f & (1 << j)) == 0))
        goto next;
    ff |= 1 << i;
  next:;
  }

  if(f != ff) ret = min(ret, solve(ff));

  REP(i,n) if((ff & (1 << i)) == 0){
    ret = min(ret, 1 + solve(ff | (1 << i)));
  }

  return dp[f] = ret;
}

int main(){
  n = getInt();
  REP(i,n) a[i] = getInt() - 1;
  memset(dp, -1, sizeof(dp));
  printf("%d\n", solve(0));
  return 0;
}
accuracy: 0.21212121212121213
time_ms: 160
memory_kb: 5128
final_rank: 3