HDU - 2224 The shortest path (双调欧几里德旅行商问题)

来源:互联网 发布:编程资料 编辑:程序博客网 时间:2024/05/19 19:57

解题思路:可以去看一下有关于双调欧几里德旅行商问题的文章,我这里只是讲解一下为什么最后输出的是dp[n][n-1] + dis[n][n-1],解决上次没有解决的问题

本来到最后面,要求的dp[n][n] = min(dp[i][n] + dis[i][n])
因为 dp[i][n] = dp[i][n - 1] + dis[n][n-1]
所以 dp[n][n] = min(dp[i][n - 1] + dis[n][n-1] + dis[i][n])

又因为dp[n][n-1] = min(dp[i][n-1] + dis[i][n]),且dp[n][n-1]前面已经求到
所以dp[n][n] = dp[n][n - 1] + dis[n][n-1]

#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std;#define N 210const double INF = 0x3f3f3f3f3f3f3f3f;struct Point {    int x, y;}P[N];double dp[N][N];double dis[N][N];int n;double len(Point a, Point b) {    return sqrt((a.x - b.x) * (a.x - b.x) * 1.0 + (a.y - b.y) * (a.y - b.y) * 1.0);}void init() {    for (int i = 1; i <= n; i++)        scanf("%d%d", &P[i].x, &P[i].y);    for (int i = 1; i <= n; i++)        for (int j = 1; j <= n; j++) {            dis[i][j] = len(P[i], P[j]);        }}void solve() {    dp[2][1] = dp[1][2] = dis[1][2];    for (int i = 3; i <= n; i++) {          dp[i][i - 1] = INF;        for (int j = 1; j < i - 1; j++) {            dp[i][j] = dp[i - 1][j] + dis[i - 1][i];            dp[i][i - 1] = min(dp[i][i-1], dp[i-1][j] + dis[j][i]);         }    }    printf("%.2lf\n", dp[n][n-1] + dis[n][n - 1]);}int main() {    while (scanf("%d", &n) != EOF) {        init();        solve();     }    return 0;}
0 0
原创粉丝点击