Problem:
Bitonic Traveling Salesman Problem (Bitonic TSP)
For given $N$ points in the 2D Euclidean plane, find the distance of the shortest tour that meets the following criteria:
Visit the points according to the following steps:
It starts from the leftmost point (starting point), goes strictly from left to right, and then visits the rightmost point (turn-around point).
Then it starts from the turn-around point, goes strictly from right to left, and then back to the starting point.
Through the processes 1. 2., the tour must visit each point at least once.
Input
The input data is given in the following format:
$N$
$x_1$ $y_1$
$x_2$ $y_2$
...
$x_N$ $y_N$
Constraints
$2 \leq N \leq 1000$
$-1000 \leq x_i, y_i \leq 1000$
$x_i$ differ from each other
The given points are already sorted by x-coordinates
Output
Print the distance of the shortest tour in a line. The output should not have an error greater than 0.0001.
Sample Input 1
3
0 0
1 1
2 0
Sample Output 1
4.82842712
Sample Input 2
4
0 1
1 2
2 0
3 1
Sample Output 2
7.30056308
Sample Input 3
5
0 0
1 2
2 1
3 2
4 0
Sample Output 3
10.94427191

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
#define reb(i,n) for (int i = 0; i < (n); i++)
#define rep(i, n0, n) for (int i = (n0); i < (n); i++)
#define repp(i, n0, n) for (int i = (n0); i <= (n); i++)
#define rrep(i, n0, n) for (int i = (n0); i >= (n); i--) 
#define bit(n,k) ((n>>k)&1)
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pl = pair<ll,ll>;
using pi = pair<int,int>;
template<class T> inline bool chmax(T& a, T b) { if(a<b) { a = b; return true;} return false; }
template<class T> inline bool chmin(T& a, T b) { if(a>b) { a = b; return true;} return false; }

void solve() {
    int N; cin >> N;
    vector<int> x(N), y(N);
    reb(i,N) cin >> x[i] >> y[i];
    vector<pi> xy(N);
    reb(i,N) xy[i] = make_pair(x[i],y[i]);
    sort(all(xy));
    auto dist = [&](int i, int j) -> double {
        return hypot(x[i]-x[j], y[i]-y[j]);
    };
    if (N == 2) {
        cout << 2 * dist(0,1) << endl;
        return;
    }

    vector<vector<double>> dp(N,vector<double>(N));
    reb(j,N-2) {
        dp[N-2][j] = dist(N-2,N-1) + dist(j,N-1);
    }

    auto findTour = [&](auto findTour, int i, int j) -> double {
        if (dp[i][j] > 0) return dp[i][j];
        dp[i][j] = min(findTour(findTour,i+1,j) + dist(i,i+1), findTour(findTour,i+1,i) + dist(j,i+1)); 
        return dp[i][j];
    };
    cout << fixed << setprecision(15);
    cout << findTour(findTour,0,0) << endl;
}

int main() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    solve();

    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 10924
final_rank: 2

code_snippet: #include<iostream>
#include<cmath>

using namespace std;
const int N = 1010;

int n;
pair<int, int> a[N];
long double dp[N][N];

long double dist(int i, int j) {
    return sqrtl((a[i].first - a[j].first) * (a[i].first - a[j].first) + (a[i].second - a[j].second) * (a[i].second - a[j].second));
}

void calc(int i, int j) {
    if(dp[i][j] != -1) return;
    if(max(i, j) == n) {
        dp[i][j] = dist(min(i, j), n);
        return;
    }
    int k = max(i, j) + 1;
    calc(k, j);
    calc(i, k);
    dp[i][j] = min(dp[i][k] + dist(j, k), dp[k][j] + dist(i, k));
}

int main() {
    cin >> n;
    for(int i = 1; i <= n; ++i) cin >> a[i].first >> a[i].second;
    for(int i = 1; i <= n; ++i) for(int j = 1; j <= n; ++j) dp[i][j] = -1;
    calc(1, 1);
    cout.precision(8);
    cout << fixed << dp[1][1] << '\n';
}
accuracy: 1
time_ms: 30
memory_kb: 19184
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;

using ll = int64_t;

double caldst(vector<vector<double>> &dst,vector<vector<double>> &xy,int a,int b){
  if(dst[a][b]!=0) return dst[a][b];
  return dst[a][b]=sqrt(pow(xy[a][0]-xy[b][0],2)+pow(xy[a][1]-xy[b][1],2));
}

int main(){
  int n;
  cin >> n;
  vector xy(n,vector<double>(2));
  for(int i=0;i<n;i++) cin >> xy[i][0] >> xy[i][1];
  
  vector dst(n,vector<double>(n,0));
  
  vector dp(n,vector<double>(n,1e9));
  dp[0][0]=0;
  for(int i=1;i<n;i++){
    for(int j=0;j<i;j++){
      if((j==0)||(i-j>1)) dp[i][j]=dp[i-1][j]+caldst(dst,xy,i-1,i);
      else{
        for(int k=0;k<j;k++){
          dp[i][j]=min(dp[i][j],dp[j][k]+caldst(dst,xy,k,i));
        }  
      }
     // cout << i << j << " " << dp[i][j] << endl;
    }
  }
  for(int i=0;i<n-1;i++){
    dp[n-1][n-1]=min(dp[n-1][n-1],dp[n-1][i]+caldst(dst,xy,i,n-1));
  }
  printf("%.8lf\n",dp[n-1][n-1]);
}
accuracy: 1
time_ms: 10
memory_kb: 18972
final_rank: 17

code_snippet: #include <bits/stdc++.h>


struct Point {
    int x, y;
    double dist(Point pt) { return std::hypot((double)pt.x - x, (double)pt.y - y); }
};


int main() {
    const int INF = 1e9;

    int N;
    std::cin >> N;

    std::vector<Point> points(N);
    for (int i = 0; i < N; i++) {
        std::cin >> points[i].x >> points[i].y;
    }

    std::vector<std::vector<double>> dp(N, std::vector<double>(N, 0.0));

    for (int j = 1; j < N; j++) {
        for (int i = 0; i < j; i++) {
            if (i == 0 && j == 1) {
                dp[i][j] = points[0].dist(points[1]);
            } else if (i < j - 1) {
                dp[i][j] = dp[i][j - 1] + points[j - 1].dist(points[j]);
            } else {
                dp[i][j] = std::numeric_limits<double>::infinity();
                for (int k = 0; k < i; k++) {
                    dp[i][j] = std::min(dp[i][j], dp[k][i] + points[k].dist(points[j]));
                }
            }
        }
    }
    double min_dist = std::numeric_limits<double>::infinity();
    for (int k = 0; k < N - 1; k++) {
        min_dist = std::min(min_dist, dp[k][N - 1] + points[k].dist(points[N - 1]));
    }

    std::cout << std::fixed << std::setprecision(10) << min_dist << std::endl;
}
accuracy: 1
time_ms: 10
memory_kb: 11004
final_rank: 5

code_snippet: #include <bits/stdc++.h>

using namespace std;

// https://www.geeksforgeeks.org/bitonic-traveling-salesman-problem/ より
const int MAX_N = 1005;
// 頂点の数
int N;
// 二次元座標
struct Point {
	double x, y;
};
Point A[MAX_N];
// 2つの点の距離
double distance(const Point& a, const Point& b)
{
	return hypot(a.x - b.x, a.y - b.y);
}
// 二次元DP
double dp[MAX_N][MAX_N];
// バイトニックツアーの距離を求めるための下請け
double findTourDistance(int i, int j)
{
	// メモ化
	if (dp[i][j] > 0)
		return dp[i][j];
	
	// dp[i][j]を更新
	dp[i][j] = min(
		findTourDistance(i + 1, j) + distance(A[i], A[i + 1]),
		findTourDistance(i + 1, i) + distance(A[j], A[i + 1])
	);

	return dp[i][j];
}
// バイトニックツアーの距離を求める
void bitonicTSP(int N)
{
	// dpの配列を初期化
	for (int i = 0; i <= N; i++)
		fill(dp[i], dp[i] + N + 1, 0.0);

	for (int j = 1; j < N - 1; j++)
		dp[N - 1][j] = distance(A[N - 1], A[N]) + distance(A[j], A[N]);
	// 答えの表示
	printf("%.8f\n", findTourDistance(1, 1));
}

int main()
{
	cin.tie(0);
	ios::sync_with_stdio(false);
	cin >> N;
	for (int i = 1; i <= N; i++)
		cin >> A[i].x >> A[i].y;
	if (N == 2) {
		printf("%.8f\n", 2.0 * distance(A[1], A[2]));
	} else {
		bitonicTSP(N);
	}

	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 11540
final_rank: 11

code_snippet: #line 1 "/home/maspy/compro/library/my_template.hpp"
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using pi = pair<ll, ll>;
using vi = vector<ll>;
using u32 = unsigned int;
using u64 = unsigned long long;
using i128 = __int128;

template <class T>
using vc = vector<T>;
template <class T>
using vvc = vector<vc<T>>;
template <class T>
using vvvc = vector<vvc<T>>;
template <class T>
using vvvvc = vector<vvvc<T>>;
template <class T>
using vvvvvc = vector<vvvvc<T>>;
template <class T>
using pq = priority_queue<T>;
template <class T>
using pqg = priority_queue<T, vector<T>, greater<T>>;

#define vec(type, name, ...) vector<type> name(__VA_ARGS__)
#define vv(type, name, h, ...) \
  vector<vector<type>> name(h, vector<type>(__VA_ARGS__))
#define vvv(type, name, h, w, ...)   \
  vector<vector<vector<type>>> name( \
      h, vector<vector<type>>(w, vector<type>(__VA_ARGS__)))
#define vvvv(type, name, a, b, c, ...)       \
  vector<vector<vector<vector<type>>>> name( \
      a, vector<vector<vector<type>>>(       \
             b, vector<vector<type>>(c, vector<type>(__VA_ARGS__))))

// https://trap.jp/post/1224/
#define FOR1(a) for (ll _ = 0; _ < ll(a); ++_)
#define FOR2(i, a) for (ll i = 0; i < ll(a); ++i)
#define FOR3(i, a, b) for (ll i = a; i < ll(b); ++i)
#define FOR4(i, a, b, c) for (ll i = a; i < ll(b); i += (c))
#define FOR1_R(a) for (ll i = (a)-1; i >= ll(0); --i)
#define FOR2_R(i, a) for (ll i = (a)-1; i >= ll(0); --i)
#define FOR3_R(i, a, b) for (ll i = (b)-1; i >= ll(a); --i)
#define FOR4_R(i, a, b, c) for (ll i = (b)-1; i >= ll(a); i -= (c))
#define overload4(a, b, c, d, e, ...) e
#define FOR(...) overload4(__VA_ARGS__, FOR4, FOR3, FOR2, FOR1)(__VA_ARGS__)
#define FOR_R(...) \
  overload4(__VA_ARGS__, FOR4_R, FOR3_R, FOR2_R, FOR1_R)(__VA_ARGS__)

#define FOR_subset(t, s) for (ll t = s; t >= 0; t = (t == 0 ? -1 : (t - 1) & s))
#define all(x) x.begin(), x.end()
#define len(x) ll(x.size())
#define elif else if

#define eb emplace_back
#define mp make_pair
#define mt make_tuple
#define fi first
#define se second

#define stoi stoll

template <typename T, typename U>
T SUM(const vector<U> &A) {
  T sum = 0;
  for (auto &&a: A) sum += a;
  return sum;
}

#define MIN(v) *min_element(all(v))
#define MAX(v) *max_element(all(v))
#define LB(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define UB(c, x) distance((c).begin(), upper_bound(all(c), (x)))
#define UNIQUE(x) sort(all(x)), x.erase(unique(all(x)), x.end())

int popcnt(int x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(ll x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 1, 2)
int topbit(int x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(u32 x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(ll x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
int topbit(u64 x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 0, 2)
int lowbit(int x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(u32 x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(ll x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }
int lowbit(u64 x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }

template <typename T>
T pick(deque<T> &que) {
  T a = que.front();
  que.pop_front();
  return a;
}

template <typename T>
T pick(pq<T> &que) {
  T a = que.top();
  que.pop();
  return a;
}

template <typename T>
T pick(pqg<T> &que) {
  assert(que.size());
  T a = que.top();
  que.pop();
  return a;
}

template <typename T>
T pick(vc<T> &que) {
  assert(que.size());
  T a = que.back();
  que.pop_back();
  return a;
}

template <typename T, typename U>
T ceil(T x, U y) {
  return (x > 0 ? (x + y - 1) / y : x / y);
}

template <typename T, typename U>
T floor(T x, U y) {
  return (x > 0 ? x / y : (x - y + 1) / y);
}

template <typename T, typename U>
pair<T, T> divmod(T x, U y) {
  T q = floor(x, y);
  return {q, x - q * y};
}

template <typename F>
ll binary_search(F check, ll ok, ll ng) {
  assert(check(ok));
  while (abs(ok - ng) > 1) {
    auto x = (ng + ok) / 2;
    tie(ok, ng) = (check(x) ? mp(x, ng) : mp(ok, x));
  }
  return ok;
}

template <typename F>
double binary_search_real(F check, double ok, double ng, int iter = 100) {
  FOR(iter) {
    double x = (ok + ng) / 2;
    tie(ok, ng) = (check(x) ? mp(x, ng) : mp(ok, x));
  }
  return (ok + ng) / 2;
}

template <class T, class S>
inline bool chmax(T &a, const S &b) {
  return (a < b ? a = b, 1 : 0);
}
template <class T, class S>
inline bool chmin(T &a, const S &b) {
  return (a > b ? a = b, 1 : 0);
}

vc<int> s_to_vi(const string &S, char first_char) {
  vc<int> A(S.size());
  FOR(i, S.size()) { A[i] = S[i] - first_char; }
  return A;
}

template <typename T, typename U>
vector<T> cumsum(vector<U> &A, int off = 1) {
  int N = A.size();
  vector<T> B(N + 1);
  FOR(i, N) { B[i + 1] = B[i] + A[i]; }
  if (off == 0) B.erase(B.begin());
  return B;
}

template <typename CNT, typename T>
vc<CNT> bincount(const vc<T> &A, int size) {
  vc<CNT> C(size);
  for (auto &&x: A) { ++C[x]; }
  return C;
}

// stable
template <typename T>
vector<int> argsort(const vector<T> &A) {
  vector<int> ids(A.size());
  iota(all(ids), 0);
  sort(all(ids),
       [&](int i, int j) { return A[i] < A[j] || (A[i] == A[j] && i < j); });
  return ids;
}

// A[I[0]], A[I[1]], ...
template <typename T>
vc<T> rearrange(const vc<T> &A, const vc<int> &I) {
  int n = len(I);
  vc<T> B(n);
  FOR(i, n) B[i] = A[I[i]];
  return B;
}
#line 1 "/home/maspy/compro/library/other/io.hpp"
// based on yosupo's fastio
#include <unistd.h>

namespace detail {
template <typename T, decltype(&T::is_modint) = &T::is_modint>
std::true_type check_value(int);
template <typename T>
std::false_type check_value(long);
} // namespace detail

template <typename T>
struct is_modint : decltype(detail::check_value<T>(0)) {};
template <typename T>
using is_modint_t = enable_if_t<is_modint<T>::value>;
template <typename T>
using is_not_modint_t = enable_if_t<!is_modint<T>::value>;

struct Scanner {
  FILE *fp;
  char line[(1 << 15) + 1];
  size_t st = 0, ed = 0;
  void reread() {
    memmove(line, line + st, ed - st);
    ed -= st;
    st = 0;
    ed += fread(line + ed, 1, (1 << 15) - ed, fp);
    line[ed] = '\0';
  }
  bool succ() {
    while (true) {
      if (st == ed) {
        reread();
        if (st == ed) return false;
      }
      while (st != ed && isspace(line[st])) st++;
      if (st != ed) break;
    }
    if (ed - st <= 50) {
      bool sep = false;
      for (size_t i = st; i < ed; i++) {
        if (isspace(line[i])) {
          sep = true;
          break;
        }
      }
      if (!sep) reread();
    }
    return true;
  }
  template <class T, enable_if_t<is_same<T, string>::value, int> = 0>
  bool read_single(T &ref) {
    if (!succ()) return false;
    while (true) {
      size_t sz = 0;
      while (st + sz < ed && !isspace(line[st + sz])) sz++;
      ref.append(line + st, sz);
      st += sz;
      if (!sz || st != ed) break;
      reread();
    }
    return true;
  }
  template <class T, enable_if_t<is_integral<T>::value, int> = 0>
  bool read_single(T &ref) {
    if (!succ()) return false;
    bool neg = false;
    if (line[st] == '-') {
      neg = true;
      st++;
    }
    ref = T(0);
    while (isdigit(line[st])) { ref = 10 * ref + (line[st++] & 0xf); }
    if (neg) ref = -ref;
    return true;
  }
  template <class T, is_modint_t<T> * = nullptr>
  bool read_single(T &ref) {
    long long val = 0;
    bool f = read_single(val);
    ref = T(val);
    return f;
  }
  bool read_single(double &ref) {
    string s;
    if (!read_single(s)) return false;
    ref = std::stod(s);
    return true;
  }
  bool read_single(char &ref) {
    string s;
    if (!read_single(s) || s.size() != 1) return false;
    ref = s[0];
    return true;
  }
  template <class T>
  bool read_single(vector<T> &ref) {
    for (auto &d: ref) {
      if (!read_single(d)) return false;
    }
    return true;
  }
  template <class T, class U>
  bool read_single(pair<T, U> &p) {
    return (read_single(p.first) && read_single(p.second));
  }
  template <class A, class B, class C>
  bool read_single(tuple<A, B, C> &p) {
    return (read_single(get<0>(p)) && read_single(get<1>(p))
            && read_single(get<2>(p)));
  }
  template <class A, class B, class C, class D>
  bool read_single(tuple<A, B, C, D> &p) {
    return (read_single(get<0>(p)) && read_single(get<1>(p))
            && read_single(get<2>(p)) && read_single(get<3>(p)));
  }
  void read() {}
  template <class H, class... T>
  void read(H &h, T &... t) {
    bool f = read_single(h);
    assert(f);
    read(t...);
  }
  Scanner(FILE *fp) : fp(fp) {}
};

struct Printer {
  Printer(FILE *_fp) : fp(_fp) {}
  ~Printer() { flush(); }

  static constexpr size_t SIZE = 1 << 15;
  FILE *fp;
  char line[SIZE], small[50];
  size_t pos = 0;
  void flush() {
    fwrite(line, 1, pos, fp);
    pos = 0;
  }
  void write(const char &val) {
    if (pos == SIZE) flush();
    line[pos++] = val;
  }
  template <class T, enable_if_t<is_integral<T>::value, int> = 0>
  void write(T val) {
    if (pos > (1 << 15) - 50) flush();
    if (val == 0) {
      write('0');
      return;
    }
    if (val < 0) {
      write('-');
      val = -val; // todo min
    }
    size_t len = 0;
    while (val) {
      small[len++] = char(0x30 | (val % 10));
      val /= 10;
    }
    for (size_t i = 0; i < len; i++) { line[pos + i] = small[len - 1 - i]; }
    pos += len;
  }
  void write(const string &s) {
    for (char c: s) write(c);
  }
  void write(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++) write(s[i]);
  }
  void write(const double &x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << x;
    string s = oss.str();
    write(s);
  }
  void write(const long double &x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << x;
    string s = oss.str();
    write(s);
  }
  template <class T, is_modint_t<T> * = nullptr>
  void write(T &ref) {
    write(ref.val);
  }
  template <class T>
  void write(const vector<T> &val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
      if (i) write(' ');
      write(val[i]);
    }
  }
  template <class T, class U>
  void write(const pair<T, U> &val) {
    write(val.first);
    write(' ');
    write(val.second);
  }
  template <class A, class B, class C>
  void write(const tuple<A, B, C> &val) {
    auto &[a, b, c] = val;
    write(a), write(' '), write(b), write(' '), write(c);
  }
  template <class A, class B, class C, class D>
  void write(const tuple<A, B, C, D> &val) {
    auto &[a, b, c, d] = val;
    write(a), write(' '), write(b), write(' '), write(c), write(' '), write(d);
  }
  template <class A, class B, class C, class D, class E>
  void write(const tuple<A, B, C, D, E> &val) {
    auto &[a, b, c, d, e] = val;
    write(a), write(' '), write(b), write(' '), write(c), write(' '), write(d), write(' '), write(e);
  }
  template <class A, class B, class C, class D, class E, class F>
  void write(const tuple<A, B, C, D, E, F> &val) {
    auto &[a, b, c, d, e, f] = val;
    write(a), write(' '), write(b), write(' '), write(c), write(' '), write(d), write(' '), write(e), write(' '), write(f);
  }
  template <class T, size_t S>
  void write(const array<T, S> &val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
      if (i) write(' ');
      write(val[i]);
    }
  }
  void write(i128 val) {
    string s;
    bool negative = 0;
    if(val < 0){
      negative = 1;
      val = -val;
    }
    while (val) {
      s += '0' + int(val % 10);
      val /= 10;
    }
    if(negative) s += "-";
    reverse(all(s));
    if (len(s) == 0) s = "0";
    write(s);
  }
};

Scanner scanner = Scanner(stdin);
Printer printer = Printer(stdout);

void flush() { printer.flush(); }
void print() { printer.write('\n'); }
template <class Head, class... Tail>
void print(Head &&head, Tail &&... tail) {
  printer.write(head);
  if (sizeof...(Tail)) printer.write(' ');
  print(forward<Tail>(tail)...);
}

void read() {}
template <class Head, class... Tail>
void read(Head &head, Tail &... tail) {
  scanner.read(head);
  read(tail...);
}

#define INT(...)   \
  int __VA_ARGS__; \
  read(__VA_ARGS__)
#define LL(...)   \
  ll __VA_ARGS__; \
  read(__VA_ARGS__)
#define STR(...)      \
  string __VA_ARGS__; \
  read(__VA_ARGS__)
#define CHAR(...)      \
  char __VA_ARGS__; \
  read(__VA_ARGS__)
#define DBL(...)      \
  double __VA_ARGS__; \
  read(__VA_ARGS__)

#define VEC(type, name, size) \
  vector<type> name(size);    \
  read(name)
#define VV(type, name, h, w)                     \
  vector<vector<type>> name(h, vector<type>(w)); \
  read(name)

void YES(bool t = 1) { print(t ? "YES" : "NO"); }
void NO(bool t = 1) { YES(!t); }
void Yes(bool t = 1) { print(t ? "Yes" : "No"); }
void No(bool t = 1) { Yes(!t); }
void yes(bool t = 1) { print(t ? "yes" : "no"); }
void no(bool t = 1) { yes(!t); }
#line 3 "main.cpp"

void solve() {
  LL(N);
  VEC(pi, XY, N);
  const ll INF = 1LL << 60;
  using Re = double;

  auto dist = [&](int i, int j) -> Re {
    auto [xi, yi] = XY[i];
    auto [xj, yj] = XY[j];
    Re dx = xi - xj;
    Re dy = yi - yj;
    return sqrt(dx * dx + dy * dy);
  };

  vv(Re, dp, N, N, INF);
  dp[0][0] = 0;
  FOR(i, N) FOR(j, N) {
    int k = max<int>(i, j);
    chmin(dp[i][k], dp[i][j] + dist(j, k));
    chmin(dp[k][j], dp[i][j] + dist(i, k));
    ++k;
    if (k == N) continue;
    chmin(dp[i][k], dp[i][j] + dist(j, k));
    chmin(dp[k][j], dp[i][j] + dist(i, k));
  }

  Re ANS = dp[N - 1][N - 1];
  print(ANS);
}

signed main() {
  cout << fixed << setprecision(15);

  ll T = 1;
  // LL(T);
  FOR(T) solve();

  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 10960
final_rank: 3

code_snippet: #include<bits/stdc++.h>
using namespace std;

#define EPS (1e-10)
#define int long long
//#define lson (rt<<1)
//#define rson (rt<<1|1)
//#define mid ((l+r)>>1)
#define mst(a) memset(a,0,sizeof(a))
#define cf int Tcodeforces, Tcodeforce;cin>>Tcodeforces;for(Tcodeforce = 1; Tcodeforce <= Tcodeforces; Tcodeforce++)
const int maxn = 1e3 +7;
const int maxm = 2e5 +7;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 +7;

int n;
double x[maxn], y[maxn];
double d[maxn][maxn];
double f[maxn][maxn];

double getf(int p1, int p2) { // p1 <= p2
    if(p1==p2&&p1==1) return 0;
    if(f[p1][p2]) return f[p1][p2];
    double res = inf;
    if(p1==p2) {
        for(int i = 1; i < p2- 1 || i == 1; i++) {
            res = min(res, getf(i,p2)+d[i][p2]);
        }
    }
    else if(p1==p2-1) {
        for(int i = 1; i < p2 - 1; i++) {
            res = min(res, getf(i,p1)+d[i][p2]);
        }
    }
    else {
        res = getf(p1,p2-1) + d[p2-1][p2];
    }
    return f[p1][p2] = res;
}

signed main() {
    #ifdef moyi_qwq
        freopen("D:/source file/intxt/in.txt","r",stdin);
    #endif
    
    cin>>n;
    for(int i = 1; i <= n; i++) {cin>>x[i]>>y[i];}
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= n; j++) {
            double dx = x[i]-x[j], dy = y[i] - y[j];
            d[i][j] = sqrt(dx*dx+dy*dy);
        }
    }
    f[1][1] = 0;
    f[1][2] = d[1][2];
    //f[2][2] = d[1][2] * 2;
    printf("%.10lf",getf(n,n));
    //cout<<getf(n,n)<<endl;


    //cerr<<"Time : "<<1000*((double)clock())/(double)CLOCKS_PER_SEC<<"ms";
    return (0);
}

/*

dp[i][j] 两条路到i和j 之间的点最多走一条 都走 i<=j
for i 1-(j-1):
    dp[i][j] = min(dp[i][j-1] + e[j-1][j],
                dp[x][j-1] + e[x][j])


*/
accuracy: 1
time_ms: 10
memory_kb: 18132
final_rank: 14

code_snippet: #include <bits/stdc++.h>

#define pb push_back
#define mp make_pair
#define X first
#define Y second
using namespace std;

typedef long long int ll;
typedef vector <int> vi;
typedef pair <int,int> pii;
const int Size=1e3+10;
const int INF=0x3f3f3f3f;

inline int read()
{
    int x=0, f=1; char ch=getchar();
    while(ch<'0' || ch>'9') {if(ch=='-') f=-1; ch=getchar();}
    while(ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
    return x*f;
}

struct point{
    double x,y;
    void init(){scanf("%lf%lf",&x,&y);}
};

point p[Size];
double dis[Size][Size];
double dp[Size][Size];
/*
dp[i][j]表示从点1连两条路径到点i、j的最短距离
（两条路径除去起点、终点可以相同，中间节点不同）
不妨设i>=j
答案为dp[n][n]
若j<i-1，点i的前一个点必然是点i-1，dp[i][j]=dp[i-1][j]+dis(i-1,i)
若j>=i-1，点i的前一个点是1~i-2，dp[i][j]=min{dp[i-1][k]+dis(k,i)+dis(i-1,j)}
*/

double get_dis(int i,int j){return hypot(p[i].x-p[j].x,p[i].y-p[j].y);}
int main()
{
    int n=read();
    for (int i=1;i<=n;++i)  p[i].init();
    for (int i=1;i<=n;++i)
        for (int j=i;j<=n;++j) dis[i][j]=dis[j][i]=get_dis(i,j);

    dp[1][1]=0;
    for (int i=2;i<=n;++i) dp[i][1]=dp[i-1][1]+dis[i-1][i];
    for (int i=2;i<=n;++i)
        for (int j=1;j<=i;++j)
    {
        if (j<i-1) {dp[i][j]=dp[i-1][j]+dis[i-1][i]; continue;}
        dp[i][j]=INF;
        for (int k=1;k<=max(i-2,1);++k)
            dp[i][j]=min(dp[i][j],dp[i-1][k]+dis[k][i]+dis[i-1][j]);
    }

    double res=dp[n][n];
    printf("%.10lf\n",res);

    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 18752
final_rank: 15

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
//double max:0x7f,0x43 min:0xfe 0x c2  int:0x3f 
//运算符 priority  后缀 前缀 */+- 位移 比较 &^| && || 赋值
using namespace std;
double f[1005][1005];
int k,n,m;
struct Node{
	double x;
	double y;
	Node(double x,double y):x(x),y(y){}
	Node(){	}
}a[1005];
double dist(int x,int y){
	return hypot((a[x].x-a[y].x),(a[x].y-a[y].y));
}
void solve(){
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i].x>>a[i].y;
	memset(f,0x7f,sizeof f);
	f[1][1]=0; 
	for(int i=2;i<=n;i++)
		for(int j=1;j<i;j++){
			if(i==2&&j==1) f[i][j]=dist(1,2);
			else if(i==j+1){
				for(int k=1;k<j;k++) f[i][j]=min(f[i][j],f[j][k]+dist(k,i)); 				
			}else{
				f[i][j]=f[i-1][j]+dist(i-1,i);
			}
		}
	double res=f[0][0];
	for(int i=1;i<=n;i++){
		res=min(res,f[n][i]+dist(i,n));
	}

	cout<<fixed<<setprecision(8)<<res<<endl;
}
int main()
{	
	//cout.setf(ios::fixed);
	//cout<<fixed<<setprecision(4)<<x<<endl;
	ios::sync_with_stdio(false);
	cin.tie(0);
	#if 0
	freopen("in.txt","r",stdin);
	freopen("out.txt","w",stdout);
	#endif 
    solve();
	#if 0
	int T;
	cin>>T;
	while(T--){
		solve();
	}
	#endif
	
	#if 0
	fclose(stdin);
	fclose(stdout);
	#endif 
    return 0;
}
//so upset dp was wrong 
/*
	because,in fact, the local optimum isn't f[j], it's f[j]+dist(a[g[j]],a[j+1]);
But we can't denote this by linear array. So we need f[i][j] to denote the first path was end with i and second path was end with j


*/
accuracy: 1
time_ms: 10
memory_kb: 11540
final_rank: 11

code_snippet: #include <iostream>
#include <vector>
#include <map>
#include <algorithm>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <iomanip>
using namespace std;
using ll = long long;
template<class T> inline bool chmax(T& a, T b){ if (a < b){ a = b; return true; } return false; }
template<class T> inline bool chmin(T& a, T b){ if (a > b){ a = b; return true; } return false; }
const double inf = 1e9;

double dist(double x, double y, double xx, double yy) {
    return sqrt((x - xx)*(x - xx) + (y - yy)*(y - yy)) ;
}

int main() {
    int n; cin >> n;
    vector<double> x(n), y(n); 
    for(int i=0; i<n; ++i) {
        cin >> x[i] >> y[i];
    }
    vector<vector<double>> dp(n, vector<double>(n, inf));
    dp[0][0] = 0.0;
    for(int i=0; i<n; ++i) {
        for(int j=0; j<n; ++j) {
            if (i + 1 < n) {
                chmin(dp[i+1][j], dp[i][j] + dist(x[i], y[i], x[i+1], y[i+1]));
                chmin(dp[i][i+1], dp[i][j] + dist(x[j], y[j], x[i+1], y[i+1]));
            }
            if (j + 1 < n) {
                chmin(dp[j+1][j], dp[i][j] + dist(x[i], y[i], x[j+1], y[j+1]));
                chmin(dp[i][j+1], dp[i][j] + dist(x[j], y[j], x[j+1], y[j+1]));
            }
        }
    }
    printf("%.12f\n", dp[n-1][n-1]);
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 11096
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;

namespace geometry{
  constexpr double eps = 1e-10;
  bool eq(double a, double b){ return fabs(a - b) < eps; }
  template<typename T>  bool eq(T a, T b){ return a == b; }
  bool is_zero(double a){ return fabs(a) < eps; }
  template<typename T> bool is_zero(T a){ return a == 0; }
  bool le(double a, double b){ return a <= b + eps; }
  template<typename T> bool le(T a, T b){ return a <= b; }
  bool lt(double a, double b){ return a < b - eps; }
  template<typename T> bool lt(T a, T b){ return a < b; }
  int sgn(double a){ return is_zero(a) ? 0 : ((a < 0) ? -1 : 1); }
  template<typename T> int sgn(T a){ return (a<0) ? -1 : ((a > 0) ? 1 : 0); }
  template<typename T> double psqrt(T a){ return sqrt(max(T(0), a)); }
};


template<class T> struct Point{
  T x,y;
  Point(){}
  Point(T x, T y) : x(x), y(y) {}
  Point(const pair<T,T> &p) : x(p.first), y(p.second) {}

  Point operator*(const T b) const { return Point(x * b, y * b); }
  Point operator/(const T b) const { return Point(x / b, y / b); }
  Point operator+(const Point &b) const { return Point(x + b.x, y + b.y); }
  Point operator-(const Point &b) const { return Point(x - b.x, y - b.y); }
  Point operator*(const Point &b) const { return Point(x*b.x - y*b.y, x*b.y + y*b.x); }
  Point operator/(const Point &b) const { return Point(x*b.x + y*b.y, y*b.x - x*b.y)/(b.x*b.x + b.y*b.y); }

  Point &operator*=(const T b){ return (*this) = (*this) * b; }
  Point &operator/=(const T b){ return (*this) = (*this) / b; }
  Point &operator+=(const Point &b){ return (*this) = (*this) + b; }
  Point &operator-=(const Point &b){ return (*this) = (*this) - b; }
  Point &operator*=(const Point &b){ return (*this) = (*this) * b; }
  Point &operator/=(const Point &b){ return (*this) = (*this) / b; }
  
  bool operator==(const Point &b) const {
    return geometry::eq(x, b.x) && geometry::eq(y, b.y);
  }
  bool operator<(const Point &b) const { 
    if(geometry::eq(x, b.x)) return y < b.y;
    return x < b.x;
  }
  T Norm() const { return x * x + y * y; }
  double Abs() const { return hypot<double>(x, y); }
  double dist(const Point &b) const { return hypot<double>(x - b.x, y - b.y); }
  double arg() const { return atan2<double>(y, x); }
  
  Point ArgVec() const {
    if((*this) == Point(0, 0)) return (*this);
    if(geometry::is_zero(x)) return Point(0, -1);
    return (*this) / gcd(x, y) * (x < 0 ? -1 : 1);
  }

  int ort() const {
    if(geometry::is_zero(x) && geometry::is_zero(y)) return 0;
    if(geometry::is_zero(y)) return x > 0 ? 1 : 3;
    if(geometry::is_zero(x)) return y > 0 ? 2 : 4;
    if (y > 0) return x > 0 ? 1 : 2;
    else return x > 0 ? 4 : 3;
  }
  Point rotate90() const { return Point(-y, x);}
  Point rotate180() const { return Point(-x, -y);}
  Point rotate270() const { return Point(y, -x);}

  Point flip_x(T p = 0) const { return Point(p*2 - x, y);}
  Point flip_y(T p = 0) const { return Point(x, p*2 - y);}

  Point rotate(double theta) const {
    return Point(cos(theta)*x - sin(theta)*y, sin(theta)*x + cos(theta)*y);
  }

  Point flip(double theta) const {
    return (*this).rotate(-theta).flip_y().rotate(theta);
  }

  friend ostream &operator<<(ostream &os, const Point &p) {
    return os << p.x << " " << p.y;
  }
  friend istream &operator>>(istream &is, Point &p) {
    T a, b; is >> a >> b;
    p = Point<T>(a, b);
    return (is);
  }
};

template<typename T> Point<T> Polar(const T& rho, const T& theta = 0){
  return Point<T>(rho * cos(theta), rho * sin(theta));
}

template<typename T> using Polygon = vector<Point<T>>;

template<class T> T Cross(const Point<T> &a, const Point<T> &b) { return a.x * b.y - a.y * b.x; }

template<class T> T Dot(const Point<T> &a, const Point<T> &b) { return a.x * b.x + a.y * b.y; }

template<class T> int iSP(const Point<T> &a, const Point<T> &b, const Point<T> &c){
  T fl = Cross(b-a, c-a);
  if(geometry::lt(T(0), fl)) return 1; // CCW
  if(geometry::lt(fl, T(0))) return -1; // CW
  if(geometry::lt(T(0), Dot(b-a, c-b))) return 2; //abc
  if(geometry::lt(T(0), Dot(a-b, c-a))) return -2; //bac
  return 0; // acb
}

template<class T> bool Intersect(const Point<T> &a, const Point<T> &b, const Point<T> &c, const Point<T> &d) {
  return (iSP(a, b, c)*iSP(a, b, d) <= 0) && (iSP(c, d, a)*iSP(c, d, b) <= 0);
}

template<class T> int angletype(const Point<T> &a, const Point<T> &b, const Point<T> &c){
  T v = Dot(a-b, c-a);
  if(geometry::is_zero(v)) return 0; // right angle
  if(v > 0) return 1; // acute angle
  return -1; // obtuse angle
}

template<typename T>
bool cmp_y(const Point<T>& p1, const Point<T> &p2){
  if(p1.y == p2.y) return p1.x < p2.x;
  return p1.y < p2.y;
}

template<typename T>
bool cmp_arg(const Point<T>& p1, const Point<T> &p2){
  if(p1.ort() != p2.ort()) return p1.ort() < p2.ort();
  return iSP(Point<T>(0,0), p1, p2) > 0;
}

template<typename T>
void ArgSort(Polygon<T> &ps){
  sort(begin(ps), end(ps), cmp_arg<T>);
}

template<typename T>
double bitonicTSP(const Polygon<T> &ps){
  int n = int(ps.size());
  vector dp(n, vector(n, 0.0));
  for(int j = 1; j < n; ++j){
    for(int i = 0; i < j; ++i){
      if(i == 0 && j == 1) dp[i][j] = ps[i].dist(ps[j]);
      else if(i < j-1) dp[i][j] = dp[i][j-1] + ps[j-1].dist(ps[j]);
      else{
        dp[i][j] = numeric_limits<double>::infinity();
        for(int k = 0; k < i; ++k) dp[i][j] = min(dp[i][j], dp[k][i] + ps[j].dist(ps[k]));
      }
    }
  }
  double ans = numeric_limits<double>::infinity();
  for(int k = 0; k < n-1; ++k) ans = min(ans, dp[k][n-1] + ps[k].dist(ps[n-1]));
  return ans;
}

int main() {
  int n; cin >> n;
  Polygon<double> ps(n);
  for(auto&p : ps) cin >> p;
  cout << fixed << setprecision(12);
  cout << bitonicTSP(ps) << "\n";
}
accuracy: 1
time_ms: 10
memory_kb: 11092
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define ll long long 
#define vi vector<int>
#define pii pair<int,int>


int n;
vector<pii> A;

double distance(int i, int j){
    return hypot(A[i].first-A[j].first,A[i].second-A[j].second);
}
double dp[1000][1000];
double solve(int i,int j){
    int k = max(i,j)+1;
    if(k==n-1){
        return distance(i,k)+distance(j,k);
    }
    if(dp[i][j]!=-1) return dp[i][j];
    //k goes top 
    double a = solve(k,j)+distance(i,k);
    //k goes bottom 
    double b = solve(i,k)+distance(j,k);
    return dp[i][j] = min(a,b);
}

int main()
{
    cin>>n;
    for(int i=0;i<n;i++){
        int x, y;
        cin>>x>>y;
        A.push_back(make_pair(x,y));
    }
    sort(A.begin(),A.end());
    for(int i=0;i<n;i++) for(int j=0;j<n;j++)
        dp[i][j] = -1;
    printf("%.8f\n",solve(0,0));




    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 11440
final_rank: 13

code_snippet: #include <bits/stdc++.h>
using namespace std;
int main(){
    int N;
    cin >> N;
    vector<int> x(N), y(N);
    for(int i = 0; i < N; i++) cin >> x[i] >> y[i];
    vector<vector<double>> d(N, vector<double>(N));
    for(int i = 0; i < N; i++){
        for(int j = 0; j < N; j++){
            d[i][j] = sqrt((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]));
        }
    }
    vector<vector<double>> dp(N, vector<double>(N, numeric_limits<double>::infinity()));
    dp[0][0] = 0;
    for(int i = 1; i < N; i++){
        for(int j = 0; j < i; j++){
            if(j == 0 && i == 1){
                dp[j][i] = d[j][i];
            }
            else if(j < i - 1){
                dp[j][i] = min(dp[j][i], dp[j][i - 1] + d[i - 1][i]);
            }
            else{
                for(int k = 0; k < i; k++){
                    dp[j][i] = min(dp[j][i], dp[k][j] + d[k][i]);
                }
            }
        }
    }
    double ans = numeric_limits<double>::infinity();
    for(int i = 0; i < N - 1; i++){
        ans = min(ans, dp[i][N - 1] + d[i][N - 1]);
    }
    printf("%.10lf\n", ans);
}
accuracy: 1
time_ms: 10
memory_kb: 18952
final_rank: 16

code_snippet: #include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <algorithm>
#include <cmath>
using namespace std;
const int max_n = 1000;
const int Inf = 0x3fffffff;
int x[max_n+1];
int y[max_n+1];
double OPT[max_n+1][max_n+1];

double Eu_dis(int i,int j){
    return(sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])));
}

int main(){
    int n;
    //n = 3;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d%d",x+i,y+i);
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            OPT[i][j] = Inf;
        }
    }
    OPT[1][1] = 0;
    for(int i=1;i<=n;i++){
        for(int j=i;j<=n;j++){
            if(j+1<=n){
                //i -> j+1
                OPT[j][j+1] = min(OPT[j][j+1],OPT[i][j]+Eu_dis(i,j+1));
                //j -> j+1
                OPT[i][j+1] = min(OPT[i][j+1],OPT[i][j]+Eu_dis(j,j+1));
            }
            //i -> j
            OPT[j][j] = min(OPT[j][j],OPT[i][j]+Eu_dis(i,j));
        }
    }
    printf("%.8lf\n",OPT[n][n]);
    //system("Pause");
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 11044
final_rank: 8

code_snippet: #include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int MAX_N = 1000;
const int INF = 0x3f3f3f3f;
double OPT[MAX_N+1][MAX_N+1];
int x[MAX_N+1], y[MAX_N+1];
double dist(int i,int j){
	int dx = x[i]-x[j];
	int dy = y[i]-y[j];
	return sqrt(dx*dx+dy*dy);
}

double solve(int N){
	for (int i = 0; i <= N; ++i)
		for (int j = 0; j <= N; ++j)
			OPT[i][j] = INF;
	OPT[1][1] = 0;

	for (int i = 1; i <= N; ++i)
		for (int j = i; j <= N; ++j){
			if(j+1 <= N)
				OPT[j][j+1] = min(OPT[j][j+1],OPT[i][j]+dist(i,j+1));
			if(j+1 <= N)
				OPT[i][j+1] = min(OPT[i][j+1],OPT[i][j]+dist(j,j+1));
			OPT[j][j] = min(OPT[j][j],OPT[i][j]+dist(i,j));
		}

	return OPT[N][N];
}

int main(){
	int N;	scanf("%d",&N);
	for (int i = 1; i <= N; ++i)
		scanf("%d%d",x+i,y+i);
	double ans = solve(N);
	printf("%.20lf\n",ans);
}
accuracy: 1
time_ms: 10
memory_kb: 10584
final_rank: 1

code_snippet: #include <bits/stdc++.h>


struct Point {
    int x, y;
    double dist(Point pt) { return std::hypot((double)pt.x - x, (double)pt.y - y); }
};


int main() {
    const int INF = 1e9;

    int N;
    std::cin >> N;

    std::vector<Point> points(N);
    for (int i = 0; i < N; i++) {
        std::cin >> points[i].x >> points[i].y;
    }

    std::vector<std::vector<double>> dp(N, std::vector<double>(N, 0.0));

    for (int j = 1; j < N; j++) {
        for (int i = 0; i < j; i++) {
            if (i == 0 && j == 1) {
                dp[i][j] = points[0].dist(points[1]);
            } else if (i < j - 1) {
                dp[i][j] = dp[i][j - 1] + points[j - 1].dist(points[j]);
            } else {
                dp[i][j] = std::numeric_limits<double>::infinity();
                for (int k = 0; k < i; k++) {
                    dp[i][j] = std::min(dp[i][j], dp[k][i] + points[k].dist(points[j]));
                }
            }
        }
    }
    double min_dist = std::numeric_limits<double>::infinity();
    for (int k = 0; k < N - 1; k++) {
        min_dist = std::min(min_dist, dp[k][N - 1] + points[k].dist(points[N - 1]));
    }

    std::cout << std::fixed << std::setprecision(10) << min_dist << std::endl;
}
accuracy: 1
time_ms: 10
memory_kb: 10964
final_rank: 4

code_snippet: #line 2 "/home/yuruhiya/programming/library/template/template.cpp"
#include <bits/stdc++.h>
#line 6 "/home/yuruhiya/programming/library/template/constants.cpp"

#define rep(i, n) for (int i = 0; i < (n); ++i)
#define FOR(i, m, n) for (int i = (m); i < (n); ++i)
#define rrep(i, n) for (int i = (n)-1; i >= 0; --i)
#define rfor(i, m, n) for (int i = (m); i >= (n); --i)
#define unless(c) if (!(c))
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define range_it(a, l, r) (a).begin() + (l), (a).begin() + (r)

using namespace std;
using ll = long long;
using LD = long double;
using VB = vector<bool>;
using VVB = vector<VB>;
using VI = vector<int>;
using VVI = vector<VI>;
using VL = vector<ll>;
using VVL = vector<VL>;
using VS = vector<string>;
using VD = vector<LD>;
using PII = pair<int, int>;
using VP = vector<PII>;
using PLL = pair<ll, ll>;
using VPL = vector<PLL>;
template <class T> using PQ = priority_queue<T>;
template <class T> using PQS = priority_queue<T, vector<T>, greater<T>>;
constexpr int inf = 1000000000;
constexpr long long inf_ll = 1000000000000000000ll, MOD = 1000000007;
constexpr long double PI = 3.14159265358979323846, EPS = 1e-12;
#line 7 "/home/yuruhiya/programming/library/template/Input.cpp"
using namespace std;

#ifdef _WIN32
#define getchar_unlocked _getchar_nolock
#define putchar_unlocked _putchar_nolock
#define fwrite_unlocked fwrite
#define fflush_unlocked fflush
#endif
class Scanner {
	static int gc() {
		return getchar_unlocked();
	}
	static char next_char() {
		char c;
		read(c);
		return c;
	}
	template <class T> static void read(T& v) {
		cin >> v;
	}
	static void read(char& v) {
		while (isspace(v = gc()))
			;
	}
	static void read(bool& v) {
		v = next_char() != '0';
	}
	static void read(string& v) {
		v.clear();
		for (char c = next_char(); !isspace(c); c = gc()) v += c;
	}
	static void read(int& v) {
		v = 0;
		bool neg = false;
		char c = next_char();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c); c = gc()) v = v * 10 + (c - '0');
		if (neg) v = -v;
	}
	static void read(long long& v) {
		v = 0;
		bool neg = false;
		char c = next_char();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c); c = gc()) v = v * 10 + (c - '0');
		if (neg) v = -v;
	}
	static void read(double& v) {
		v = 0;
		double dp = 1;
		bool neg = false, after_dp = false;
		char c = next_char();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c) || c == '.'; c = gc()) {
			if (c == '.') {
				after_dp = true;
			} else if (after_dp) {
				v += (c - '0') * (dp *= 0.1);
			} else {
				v = v * 10 + (c - '0');
			}
		}
		if (neg) v = -v;
	}
	static void read(long double& v) {
		v = 0;
		long double dp = 1;
		bool neg = false, after_dp = false;
		char c = next_char();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c) || c == '.'; c = gc()) {
			if (c == '.') {
				after_dp = true;
			} else if (after_dp) {
				v += (c - '0') * (dp *= 0.1);
			} else {
				v = v * 10 + (c - '0');
			}
		}
		if (neg) v = -v;
	}
	template <class T, class U> static void read(pair<T, U>& v) {
		read(v.first);
		read(v.second);
	}
	template <class T> static void read(vector<T>& v) {
		for (auto& e : v) read(e);
	}
	template <size_t N = 0, class T> static void read_tuple_impl(T& v) {
		if constexpr (N < tuple_size_v<T>) {
			read(get<N>(v));
			read_tuple_impl<N + 1>(v);
		}
	}
	template <class... T> static void read(tuple<T...>& v) {
		read_tuple_impl(v);
	}
	struct ReadVectorHelper {
		size_t n;
		ReadVectorHelper(size_t _n) : n(_n) {}
		template <class T> operator vector<T>() {
			vector<T> v(n);
			read(v);
			return v;
		}
	};
	struct Read2DVectorHelper {
		size_t n, m;
		Read2DVectorHelper(const pair<size_t, size_t>& nm) : n(nm.first), m(nm.second) {}
		template <class T> operator vector<vector<T>>() {
			vector<vector<T>> v(n, vector<T>(m));
			read(v);
			return v;
		}
	};

public:
	string read_line() const {
		string v;
		for (char c = gc(); c != '\n' && c != '\0'; c = gc()) v += c;
		return v;
	}
	template <class T> T read() const {
		T v;
		read(v);
		return v;
	}
	template <class T> vector<T> read_vector(size_t n) const {
		vector<T> a(n);
		read(a);
		return a;
	}
	template <class T> operator T() const {
		return read<T>();
	}
	int operator--(int) const {
		return read<int>() - 1;
	}
	ReadVectorHelper operator[](size_t n) const {
		return ReadVectorHelper(n);
	}
	Read2DVectorHelper operator[](const pair<size_t, size_t>& nm) const {
		return Read2DVectorHelper(nm);
	}
	void operator()() const {}
	template <class H, class... T> void operator()(H&& h, T&&... t) const {
		read(h);
		operator()(forward<T>(t)...);
	}

private:
	template <template <class...> class, class...> struct Multiple;
	template <template <class...> class V, class Head, class... Tail>
	struct Multiple<V, Head, Tail...> {
		template <class... Args> using vec = V<vector<Head>, Args...>;
		using type = typename Multiple<vec, Tail...>::type;
	};
	template <template <class...> class V> struct Multiple<V> { using type = V<>; };
	template <class... T> using multiple_t = typename Multiple<tuple, T...>::type;
	template <size_t N = 0, class T> void multiple_impl(T& t) const {
		if constexpr (N < tuple_size_v<T>) {
			auto& vec = get<N>(t);
			using V = typename remove_reference_t<decltype(vec)>::value_type;
			vec.push_back(read<V>());
			multiple_impl<N + 1>(t);
		}
	}

public:
	template <class... T> auto multiple(size_t h) const {
		multiple_t<T...> result;
		while (h--) multiple_impl(result);
		return result;
	}
} in;
#define inputs(T, ...) \
	T __VA_ARGS__;     \
	in(__VA_ARGS__)
#define ini(...) inputs(int, __VA_ARGS__)
#define inl(...) inputs(long long, __VA_ARGS__)
#define ins(...) inputs(string, __VA_ARGS__)
#line 7 "/home/yuruhiya/programming/library/template/Output.cpp"
#include <charconv>
#line 10 "/home/yuruhiya/programming/library/template/Output.cpp"
using namespace std;

struct BoolStr {
	const char *t, *f;
	BoolStr(const char* _t, const char* _f) : t(_t), f(_f) {}
} Yes("Yes", "No"), yes("yes", "no"), YES("YES", "NO"), Int("1", "0");
struct DivStr {
	const char *d, *l;
	DivStr(const char* _d, const char* _l) : d(_d), l(_l) {}
} spc(" ", "\n"), no_spc("", "\n"), end_line("\n", "\n"), comma(",", "\n"),
    no_endl(" ", "");
class Printer {
	BoolStr B{Yes};
	DivStr D{spc};

public:
	void print(int v) const {
		char buf[12]{};
		if (auto [ptr, e] = to_chars(begin(buf), end(buf), v); e == errc{}) {
			fwrite(buf, sizeof(char), ptr - buf, stdout);
		} else {
			assert(false);
		}
	}
	void print(long long v) const {
		char buf[21]{};
		if (auto [ptr, e] = to_chars(begin(buf), end(buf), v); e == errc{}) {
			fwrite(buf, sizeof(char), ptr - buf, stdout);
		} else {
			assert(false);
		}
	}
	void print(bool v) const {
		print(v ? B.t : B.f);
	}
	void print(vector<bool>::reference v) const {
		print(v ? B.t : B.f);
	}
	void print(char v) const {
		putchar_unlocked(v);
	}
	void print(const char* v) const {
		fwrite_unlocked(v, 1, strlen(v), stdout);
	}
	void print(double v) const {
		printf("%.20f", v);
	}
	void print(long double v) const {
		printf("%.20Lf", v);
	}
	template <class T> void print(const T& v) const {
		cout << v;
	}
	template <class T, class U> void print(const pair<T, U>& v) const {
		print(v.first);
		print(D.d);
		print(v.second);
	}
	template <class InputIterater>
	void print_range(const InputIterater& begin, const InputIterater& end) const {
		for (InputIterater i = begin; i != end; ++i) {
			if (i != begin) print(D.d);
			print(*i);
		}
	}
	template <class T> void print(const vector<T>& v) const {
		print_range(v.begin(), v.end());
	}
	template <class T, size_t N> void print(const array<T, N>& v) const {
		print_range(v.begin(), v.end());
	}
	template <class T> void print(const vector<vector<T>>& v) const {
		for (size_t i = 0; i < v.size(); ++i) {
			if (i) print(D.l);
			print(v[i]);
		}
	}

	Printer() = default;
	Printer(const BoolStr& _boolstr, const DivStr& _divstr) : B(_boolstr), D(_divstr) {}
	Printer& operator()() {
		print(D.l);
		return *this;
	}
	template <class H> Printer& operator()(H&& h) {
		print(h);
		print(D.l);
		return *this;
	}
	template <class H, class... T> Printer& operator()(H&& h, T&&... t) {
		print(h);
		print(D.d);
		return operator()(forward<T>(t)...);
	}
	template <class InputIterator>
	Printer& range(const InputIterator& begin, const InputIterator& end) {
		print_range(begin, end);
		print(D.l);
		return *this;
	}
	template <class T> Printer& range(const T& a) {
		range(a.begin(), a.end());
		return *this;
	}
	template <class... T> void exit(T&&... t) {
		operator()(forward<T>(t)...);
		std::exit(EXIT_SUCCESS);
	}
	Printer& flush() {
		fflush_unlocked(stdout);
		return *this;
	}
	Printer& set(const BoolStr& b) {
		B = b;
		return *this;
	}
	Printer& set(const DivStr& d) {
		D = d;
		return *this;
	}
	Printer& set(const char* t, const char* f) {
		B = BoolStr(t, f);
		return *this;
	}
} out;
#line 3 "/home/yuruhiya/programming/library/template/Step.cpp"
using namespace std;

template <class T> struct Step {
	using value_type = T;

	class iterator {
		value_type a, b, c;

	public:
		constexpr iterator() : a(value_type()), b(value_type()), c(value_type()) {}
		constexpr iterator(value_type _b, value_type _c, value_type _s)
		    : a(_b), b(_c), c(_s) {}
		constexpr iterator& operator++() {
			--b;
			a += c;
			return *this;
		}
		constexpr iterator operator++(int) {
			iterator tmp = *this;
			--b;
			a += c;
			return tmp;
		}
		constexpr const value_type& operator*() const {
			return a;
		}
		constexpr const value_type* operator->() const {
			return &a;
		}
		constexpr bool operator==(const iterator& i) const {
			return b == i.b;
		}
		constexpr bool operator!=(const iterator& i) const {
			return !(b == i.b);
		}
		constexpr value_type start() const {
			return a;
		}
		constexpr value_type size() const {
			return b;
		}
		constexpr value_type step() const {
			return c;
		}
	};
	constexpr Step(value_type b, value_type c, value_type s) : be(b, c, s) {}
	constexpr iterator begin() const {
		return be;
	}
	constexpr iterator end() const {
		return en;
	}
	constexpr value_type start() const {
		return be.start();
	}
	constexpr value_type size() const {
		return be.size();
	}
	constexpr value_type step() const {
		return be.step();
	}
	constexpr value_type sum() const {
		return start() * size() + step() * (size() * (size() - 1) / 2);
	}
	operator vector<value_type>() const {
		return to_a();
	}
	auto to_a() const {
		vector<value_type> result;
		result.reserve(size());
		for (auto i : *this) {
			result.push_back(i);
		}
		return result;
	}

private:
	iterator be, en;
};
template <class T> constexpr auto step(T a) {
	return Step<T>(0, a, 1);
}
template <class T> constexpr auto step(T a, T b) {
	return Step<T>(a, b - a, 1);
}
template <class T> constexpr auto step(T a, T b, T c) {
	return Step<T>(a, a < b ? (b - a - 1) / c + 1 : 0, c);
}
#line 8 "/home/yuruhiya/programming/library/template/Ruby.cpp"
using namespace std;

template <class F> struct Callable {
	F func;
	Callable(const F& f) : func(f) {}
};
template <class T, class F> auto operator|(const T& v, const Callable<F>& c) {
	return c.func(v);
}

struct Sort_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			sort(begin(v), end(v), f);
			return v;
		});
	}
	template <class T> friend auto operator|(T v, [[maybe_unused]] const Sort_impl& c) {
		sort(begin(v), end(v));
		return v;
	}
} Sort;
struct SortBy_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			sort(begin(v), end(v),
			     [&](const auto& i, const auto& j) { return f(i) < f(j); });
			return v;
		});
	}
} SortBy;
struct RSort_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			sort(rbegin(v), rend(v), f);
			return v;
		});
	}
	template <class T> friend auto operator|(T v, [[maybe_unused]] const RSort_impl& c) {
		sort(rbegin(v), rend(v));
		return v;
	}
} RSort;
struct RSortBy_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			sort(begin(v), end(v),
			     [&](const auto& i, const auto& j) { return f(i) > f(j); });
			return v;
		});
	}
} RSortBy;
struct Reverse_impl {
	template <class T> friend auto operator|(T v, const Reverse_impl& c) {
		reverse(begin(v), end(v));
		return v;
	}
} Reverse;
struct Unique_impl {
	template <class T> friend auto operator|(T v, const Unique_impl& c) {
		v.erase(unique(begin(v), end(v), end(v)));
		return v;
	}
} Unique;
struct Uniq_impl {
	template <class T> friend auto operator|(T v, const Uniq_impl& c) {
		sort(begin(v), end(v));
		v.erase(unique(begin(v), end(v)), end(v));
		return v;
	}
} Uniq;
struct Rotate_impl {
	auto operator()(int&& left) {
		return Callable([&](auto v) {
			int s = static_cast<int>(size(v));
			assert(-s <= left && left <= s);
			if (0 <= left) {
				rotate(begin(v), begin(v) + left, end(v));
			} else {
				rotate(begin(v), end(v) + left, end(v));
			}
			return v;
		});
	}
} Rotate;
struct Max_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) { return *max_element(begin(v), end(v), f); });
	}
	template <class T> friend auto operator|(T v, const Max_impl& c) {
		return *max_element(begin(v), end(v));
	}
} Max;
struct Min_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) { return *min_element(begin(v), end(v), f); });
	}
	template <class T> friend auto operator|(T v, const Min_impl& c) {
		return *min_element(begin(v), end(v));
	}
} Min;
struct MaxPos_impl {
	template <class T> friend auto operator|(T v, const MaxPos_impl& c) {
		return max_element(begin(v), end(v)) - begin(v);
	}
} MaxPos;
struct MinPos_impl {
	template <class T> friend auto operator|(T v, const MinPos_impl& c) {
		return min_element(begin(v), end(v)) - begin(v);
	}
} MinPos;
struct MaxBy_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			auto max_it = begin(v);
			auto max_val = f(*max_it);
			for (auto it = next(begin(v)); it != end(v); ++it) {
				if (auto val = f(*it); max_val < val) {
					max_it = it;
					max_val = val;
				}
			}
			return *max_it;
		});
	}
} MaxBy;
struct MinBy_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			auto min_it = begin(v);
			auto min_val = f(*min_it);
			for (auto it = next(begin(v)); it != end(v); ++it) {
				if (auto val = f(*it); min_val > val) {
					min_it = it;
					min_val = val;
				}
			}
			return *min_it;
		});
	}
} MinBy;
struct MaxOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			auto max_val = f(*begin(v));
			for (auto it = next(begin(v)); it != end(v); ++it) {
				if (auto val = f(*it); max_val < val) {
					max_val = val;
				}
			}
			return max_val;
		});
	}
} MaxOf;
struct MinOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			auto min_val = f(*begin(v));
			for (auto it = next(begin(v)); it != end(v); ++it) {
				if (auto val = f(*it); min_val > val) {
					min_val = val;
				}
			}
			return min_val;
		});
	}
} MinOf;
struct Count_impl {
	template <class V> auto operator()(const V& val) {
		return Callable([&](auto v) { return count(begin(v), end(v), val); });
	}
} Count;
struct CountIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) { return count_if(begin(v), end(v), f); });
	}
} CountIf;
struct Index_impl {
	template <class V> auto operator()(const V& val) {
		return Callable([&](auto v) -> optional<int> {
			auto result = find(begin(v), end(v), val);
			return result != end(v) ? optional(result - begin(v)) : nullopt;
		});
	}
	template <class V> auto operator()(const V& val, size_t i) {
		return Callable([&](auto v) -> optional<int> {
			auto result = find(next(begin(v), i), end(v), val);
			return result != end(v) ? optional(result - begin(v)) : nullopt;
		});
	}
} Index;
struct IndexIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) -> optional<int> {
			auto result = find_if(begin(v), end(v), f);
			return result != end(v) ? optional(result - begin(v)) : nullopt;
		});
	}
} IndexIf;
struct FindIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) -> optional<typename decltype(v)::value_type> {
			auto result = find_if(begin(v), end(v), f);
			return result != end(v) ? optional(*result) : nullopt;
		});
	}
} FindIf;
struct Sum_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			return accumulate(next(begin(v)), end(v), f(*begin(v)),
			                  [&](const auto& a, const auto& b) { return a + f(b); });
		});
	}
	template <class T> friend auto operator|(T v, const Sum_impl& c) {
		return accumulate(begin(v), end(v), typename T::value_type{});
	}
} Sum;
struct Includes {
	template <class V> auto operator()(const V& val) {
		return Callable([&](auto v) { return find(begin(v), end(v), val) != end(v); });
	}
} Includes;
struct IncludesIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) { return find_if(begin(v), end(v), f) != end(v); });
	}
} IncludesIf;
struct RemoveIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) {
			v.erase(remove_if(begin(v), end(v), f), end(v));
			return v;
		});
	}
} RemoveIf;
struct Each_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			for (const auto& i : v) {
				f(i);
			}
		});
	}
} Each;
struct EachConsPair_impl {
	template <class T, class value_type = typename T::value_type>
	friend auto operator|(const T& v, EachConsPair_impl& c) {
		vector<pair<value_type, value_type>> result;
		if (size(v) >= 2) {
			result.reserve(size(v) - 1);
			for (size_t i = 0; i < size(v) - 1; ++i) {
				result.emplace_back(v[i], v[i + 1]);
			}
		}
		return result;
	}
} EachConsPair;
struct Select_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			using value_type = typename decltype(v)::value_type;
			vector<value_type> result;
			for (const auto& i : v) {
				if (f(i)) result.push_back(i);
			}
			return result;
		});
	}
} Select;
struct Map_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			using result_type = invoke_result_t<F, typename decltype(v)::value_type>;
			vector<result_type> result;
			result.reserve(size(v));
			for (const auto& i : v) {
				result.push_back(f(i));
			}
			return result;
		});
	}
} Map;
struct Indexed_impl {
	template <class T> friend auto operator|(const T& v, Indexed_impl& c) {
		using value_type = typename T::value_type;
		vector<pair<value_type, int>> result;
		result.reserve(size(v));
		int index = 0;
		for (const auto& i : v) {
			result.emplace_back(i, index++);
		}
		return result;
	}
} Indexed;
struct AllOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			for (const auto& i : v) {
				if (!f(i)) return false;
			}
			return true;
		});
	}
} AllOf;
struct AnyOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			for (const auto& i : v) {
				if (f(i)) return true;
			}
			return false;
		});
	}
} AnyOf;
struct NoneOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			for (const auto& i : v) {
				if (f(i)) return false;
			}
			return true;
		});
	}
} NoneOf;

struct Tally_impl {
	template <class F> auto operator()(size_t max_val) {
		return Callable([&](auto v) {
			vector<size_t> result(max_val);
			for (const auto& i : v) {
				result[static_cast<size_t>(i)]++;
			}
			return result;
		});
	}
	template <class T, class value_type = typename T::value_type>
	friend auto operator|(const T& v, Tally_impl& c) {
		map<value_type, size_t> result;
		for (const auto& i : v) {
			result[i]++;
		}
		return result;
	}
} Tally;

template <class T> auto operator*(const vector<T>& a, size_t n) {
	T result;
	for (size_t i = 0; i < n; ++i) {
		result.insert(result.end(), a.begin(), a.end());
	}
	return result;
}
auto operator*(string a, size_t n) {
	string result;
	for (size_t i = 0; i < n; ++i) {
		result += a;
	}
	return result;
}
template <class T, class U> auto& operator<<(vector<T>& a, const U& b) {
	a.insert(a.end(), all(b));
	return a;
}
template <class T> auto& operator<<(string& a, const T& b) {
	a.insert(a.end(), all(b));
	return a;
}
template <class T, class U> auto operator+(vector<T> a, const U& b) {
	a << b;
	return a;
}
template <class T> auto operator+(string a, const T& b) {
	a << b;
	return a;
}
#line 7 "/home/yuruhiya/programming/library/template/functions.cpp"
using namespace std;

template <class T = long long> constexpr T TEN(size_t n) {
	T result = 1;
	for (size_t i = 0; i < n; ++i) result *= 10;
	return result;
}
template <class T, class U,
          enable_if_t<is_integral_v<T> && is_integral_v<U>, nullptr_t> = nullptr>
constexpr auto div_ceil(T n, U m) {
	return (n + m - 1) / m;
}
template <class T, class U> constexpr auto div_ceil2(T n, U m) {
	return div_ceil(n, m) * m;
}
template <class T> constexpr T triangle(T n) {
	return (n & 1) ? (n + 1) / 2 * n : n / 2 * (n + 1);
}
template <class T> constexpr T nC2(T n) {
	return (n & 1) ? (n - 1) / 2 * n : n / 2 * (n - 1);
}
template <class T, class U> constexpr auto middle(const T& l, const U& r) {
	return l + (r - l) / 2;
}
template <class T, class U, class V>
constexpr bool in_range(const T& v, const U& lower, const V& upper) {
	return lower <= v && v < upper;
}
template <class T, enable_if_t<is_integral_v<T>, nullptr_t> = nullptr>
constexpr bool is_square(T n) {
	T s = sqrt(n);
	return s * s == n || (s + 1) * (s + 1) == n;
}
template <class T = long long> constexpr T BIT(int b) {
	return T(1) << b;
}
template <class T> constexpr int BIT(T x, int i) {
	return (x & (T(1) << i)) ? 1 : 0;
}
template <class T> constexpr int Sgn(T x) {
	return (0 < x) - (0 > x);
}
template <class T, class U, enable_if_t<is_integral_v<U>, nullptr_t> = nullptr>
constexpr T Pow(T a, U n) {
	assert(n >= 0);
	T result = 1;
	while (n > 0) {
		if (n & 1) {
			result *= a;
			n--;
		} else {
			a *= a;
			n >>= 1;
		}
	}
	return result;
}
template <class T, class U, enable_if_t<is_integral_v<U>, nullptr_t> = nullptr>
constexpr T Powmod(T a, U n, T mod) {
	assert(n >= 0);
	if (a > mod) a %= mod;
	T result = 1;
	while (n > 0) {
		if (n & 1) {
			result = result * a % mod;
			n--;
		} else {
			a = a * a % mod;
			n >>= 1;
		}
	}
	return result;
}
template <class T> bool chmax(T& a, const T& b) {
	if (a < b) {
		a = b;
		return true;
	}
	return false;
}
template <class T> bool chmin(T& a, const T& b) {
	if (a > b) {
		a = b;
		return true;
	}
	return false;
}
template <class T> int sz(const T& v) {
	return v.size();
}
template <class T, class U> int lower_index(const T& a, const U& v) {
	return lower_bound(all(a), v) - a.begin();
}
template <class T, class U> int upper_index(const T& a, const U& v) {
	return upper_bound(all(a), v) - a.begin();
}
template <class T> auto Slice(const T& v, size_t i, size_t len) {
	return i < v.size() ? T(v.begin() + i, v.begin() + min(i + len, v.size())) : T();
}
template <class T, class U = typename T::value_type> U Gcdv(const T& v) {
	return accumulate(next(v.begin()), v.end(), U(*v.begin()), gcd<U, U>);
}
template <class T, class U = typename T::value_type> U Lcmv(const T& v) {
	return accumulate(next(v.begin()), v.end(), U(*v.begin()), lcm<U, U>);
}
namespace internal {
	template <class T, size_t N> auto make_vector(vector<int>& sizes, const T& init) {
		if constexpr (N == 1) {
			return vector(sizes[0], init);
		} else {
			int size = sizes[N - 1];
			sizes.pop_back();
			return vector(size, make_vector<T, N - 1>(sizes, init));
		}
	}
}  // namespace internal
template <class T, size_t N>
auto make_vector(const int (&sizes)[N], const T& init = T()) {
	vector s(rbegin(sizes), rend(sizes));
	return internal::make_vector<T, N>(s, init);
}
#line 9 "/home/yuruhiya/programming/library/template/template.cpp"
#if __has_include(<library/dump.hpp>)
#include <library/dump.hpp>
#define LOCAL
#else
#define dump(...) ((void)0)
#endif

template <class T> constexpr T oj_local(const T& oj, const T& local) {
#ifndef LOCAL
	return oj;
#else
	return local;
#endif
}
#line 2 "a.cpp"

int main() {
	ini(n);
	auto [x, y] = in.multiple<LD, LD>(n);

	auto dist = [&](int i, int j) {
		return hypot(x[i] - x[j], y[i] - y[j]);
	};

	auto dp = make_vector<LD>({n, n}, -1);
	auto rec = [&](auto&& f, int i, int j) -> LD {
		LD& res = dp[i][j];
		if (res != -1) {
			return res;
		} else if (i == 0 && j == 1) {
			return res = dist(i, j);
		} else if (i < j - 1) {
			return res = f(f, i, j - 1) + dist(j - 1, j);
		} else {
			res = 1e18;
			rep(k, j - 1) chmin(res, f(f, k, j - 1) + dist(k, j));
			return res;
		}
	};

	LD ans = 1e18;
	rep(i, n - 1) {
		dump(i, n - 1, rec(rec, i, n - 1));
		chmin(ans, rec(rec, i, n - 1) + dist(i, n - 1));
	}
	out(ans);
}
accuracy: 1
time_ms: 40
memory_kb: 18880
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;

__attribute__((constructor))
void fast_io() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
}

int main() {
    int n;
    cin >> n;
    vector<int> x(n), y(n);
    for (int i = 0; i < n; ++i) cin >> x[i] >> y[i];
    auto dist = [&](int i, int j) { return hypot(x[i] - x[j], y[i] - y[j]); };
    vector dp(n, vector(n, DBL_MAX));
    dp[0][1] = dist(0, 1);
    for (int j = 2; j < n; ++j) {
        for (int i = 0; i < j - 1; ++i) {
            dp[i][j] = min(dp[i][j], dp[i][j - 1] + dist(j - 1, j));
            dp[j - 1][j] = min(dp[j - 1][j], dp[i][j - 1] + dist(i, j));
        }
    }
    double ans = DBL_MAX;
    for (int i = 0; i < n; ++i) ans = min(ans, dp[i][n-1] + dist(i, n - 1));
    cout << fixed << setprecision(8) << ans << '\n';
}
accuracy: 1
time_ms: 10
memory_kb: 11032
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;

__attribute__((constructor))
void fast_io() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
}

int main() {
    int n;
    cin >> n;
    vector<int> x(n), y(n);
    for (int i = 0; i < n; ++i) cin >> x[i] >> y[i];
    auto dist = [&](int i, int j) { return hypot(x[i] - x[j], y[i] - y[j]); };
    vector dp(n, vector(n, DBL_MAX));
    dp[0][1] = dist(0, 1);
    for (int j = 2; j < n; ++j) {
        for (int i = 0; i < j - 1; ++i) {
            dp[i][j] = min(dp[i][j], dp[i][j - 1] + dist(j - 1, j));
            dp[j - 1][j] = min(dp[j - 1][j], dp[i][j - 1] + dist(i, j));
        }
    }
    double ans = DBL_MAX;
    for (int i = 0; i < n; ++i) ans = min(ans, dp[i][n-1] + dist(i, n - 1));
    cout << fixed << setprecision(8) << ans << '\n';
}
accuracy: 1
time_ms: 10
memory_kb: 11032
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;

int main() {
    int n;
    cin >> n;
    vector<int> x(n), y(n);
    for (int i = 0; i < n; ++i) cin >> x[i] >> y[i];

    vector dist(n, vector<double>(n));
    for (int i = 0; i < n; ++i) for (int j = i; j < n; ++j)
        dist[i][j] = dist[j][i] = hypot(x[i] - x[j], y[i] - y[j]);

    vector dp(n, vector(n, DBL_MAX));
    dp[0][1] = dist[0][1];
    for (int j = 2; j < n; ++j) {
        for (int i = 0; i < j - 1; ++i) {
            dp[i][j] = min(dp[i][j], dp[i][j - 1] + dist[j - 1][j]);
            dp[j - 1][j] = min(dp[j - 1][j], dp[i][j - 1] + dist[i][j]);
        }
    }
    double ans = DBL_MAX;
    for (int i = 0; i < n; ++i) ans = min(ans, dp[i][n-1] + dist[i][n-1]);
    cout << fixed << setprecision(8) << ans << '\n';
}
accuracy: 1
time_ms: 10
memory_kb: 18988
final_rank: 18