Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

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

Solution in C# (judge verdict: Accepted)

using System;

public static class Program
{
    private struct Point
    {
        public double X;
        public double Y;

        public static double Distance(Point p, Point q)
        {
            var dx = p.X - q.X;
            var dy = p.Y - q.Y;
            return Math.Sqrt(dx * dx + dy * dy);
        }
    }

    public static void Main()
    {
        Point[] points = ReadInput();
        double result = OptBitonicTraverse(points);
        OutputResult(result);
    }

    static Point[] ReadInput()
    {
        var pointCount = Convert.ToInt32(Console.ReadLine());
        var ret = new Point[pointCount];
        for (int i = 0; i < pointCount; i++)
        {
            var segments = Console.ReadLine().Split(' ');
            ret[i] = new Point { X = Convert.ToDouble(segments[0]), Y = Convert.ToDouble(segments[1]) };
        }
        return ret;
    }

    static void OutputResult(double result)
    {
        Console.WriteLine(result);
    }

    static double OptBitonicTraverse(Point[] points)
    {
        var n = points.Length;
        if (n == 0 || n == 1)
        {
            return 0.0;
        }

        var d = new double[n, n];
        for (int i = 0; i < n - 1; i++)
        {
            for (int j = i + 1; j < n; j++)
            {
                d[i, j] = Point.Distance(points[i], points[j]);
            }
        }

        var b = new double[n, n];
        b[0, 1] = d[0, 1];
        for (int j = 2; j < n; j++)
        {
            b[j - 1, j] = double.PositiveInfinity;
            for (int k = 0; k < j - 1; k++)
            {
                var newValue = b[k, j - 1] + d[k, j];
                if (newValue < b[j - 1, j])
                {
                    b[j - 1, j] = newValue;
                }
            }

            for (int i = 0; i < j - 1; i++)
            {
                b[i, j] = b[i, j - 1] + d[j - 1, j];
            }
        }

        b[n - 1, n - 1] = b[n - 2, n - 1] + d[n - 2, n - 1];
        return b[n - 1, n - 1];
    }
}