POJ2677.Tour

来源:互联网 发布:js表单提交 编辑:程序博客网 时间:2024/05/22 17:06

试题请参见: http://poj.org/problem?id=2677

题目概述

John Doe, a skilled pilot, enjoys traveling. While on vacation, he rents a small plane and starts visiting beautiful places. To save money, John must determine the shortest closed tour that connects his destinations. Each destination is represented by a point in the plane pi = < xi,yi >. John uses the following strategy: he starts from the leftmost point, then he goes strictly left to right to the rightmost point, and then he goes strictly right back to the starting point. It is known that the points have distinct x-coordinates.

Write a program that, given a set of n points in the plane, computes the shortest closed tour that connects the points according to John’s strategy.

解题思路

对所有点按照横坐标排序.

假设从点Pi到点Pj的路线是从Pi出发, 从右至左至P1, 再从左至右至Pj. 并且保证Pi和Pmax(i, j)中的每个点恰好经过一次. 我们定义d(i, j)为Pi到点Pj的最短路径. 由于对称性, 我们只考虑i≥j的情况. 另外, 我们将Pi和Pj间的距离记作∆(i, j).

我们需要计算d(n, n). 很显然Pn到Pn的最短路径可能是从P1至Pn, P2至Pn, …, Pn-1至Pn. 则:
d(n,n)=min{d(n,1)+∆(n,1),d(n,2)+∆(n,2),…,d(n,n-1)+∆(n,n-1)}

对于计算d(i,j), 并且i≥j. 初始条件为d(2, 1)= ∆(2, 1).

  • 若j<i-1, 那么 d(i,j)=d(i-1,j)+∆(i,i-1)
  • 若j=i-1, 那么 d(i,i-1)=min{d(1,i-1)+∆(1,i),d(2,i-1)+∆(2,i),…,d(i-2,i-1)+∆(i-2,i)}.

根据对称性d(i,j) = d(j, i).

源代码

import java.text.DecimalFormat;import java.util.Arrays;import java.util.Scanner;public class Main {    private class Point implements Comparable<Point> {        public Point(int x, int y) {            this.x = x;            this.y = y;        }        @Override        public int compareTo(Point p) {            return this.x - p.x;        }        public int x;        public int y;    }    public double getMinDistance(Point[] points) {        int n = points.length;        if ( n == 1 ) {            return 0;        }        double[][] delta = new double[n][n];        double[][] d = new double[n][n];        Arrays.sort(points);        for ( int i = 0; i < n; ++ i ) {            for ( int j = 0; j < i; ++ j ) {                delta[i][j] = getDistance(points[i], points[j]);                delta[j][i] = delta[i][j];            }        }        for ( int i = 0; i < n; ++ i ) {            d[i][0] = delta[i][0];        }        for( int i = 1; i < n - 1; ++ i ) {            d[i + 1][i] = Integer.MAX_VALUE;            for( int j = 0; j < i; ++ j ) {                d[i + 1][j] = d[i][j] + delta[i][i + 1];                d[i + 1][i] = Math.min(d[i + 1][i], d[i][j] + delta[i + 1][j]);            }        }        return d[n - 1][n - 2] + delta[n - 1][n - 2];    }    private double getDistance(Point a, Point b) {        return Math.sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));    }    public static void main(String[] args) {        Main s = new Main();        Scanner in = new Scanner(System.in);        while ( in.hasNext() ) {            int n = in.nextInt();            Point[] points = new Point[n];            for ( int i = 0; i < n; ++ i ) {                int x = in.nextInt();                int y = in.nextInt();                points[i] = s.new Point(x, y);            }            DecimalFormat df = new DecimalFormat("0.00");             System.out.println(df.format(s.getMinDistance(points)));        }        in.close();    }}

参考资料

  • http://www.cnblogs.com/vongang/archive/2012/09/15/2686576.html
  • http://www.cnblogs.com/-sunshine/archive/2012/07/23/2605251.html
0 0