UVA 1347 Tour 雙調旅行商

2021-06-28 16:28:55 字數 1353 閱讀 5303

題意:平面上有n個點。乙個人要從左上角的點向右走,到右下角的點,然後再回到左上角的點。現在想讓這個人每個點到達一次,且走的總路程的距離最小。求出最小的距離。

思路:雙調旅行商問題。

因為起點和中途點已知,我們可以把這個問題轉化成兩個人從左上角出發,分別不重複的到達其他點,最後在右下角的點匯合。

可以注意到,在這個過程中,兩個人位於的點,他們經過的點,這三個就可以描述他們的狀態。

定義dp[i][j]為乙個人在點i,乙個人在點j,他們經過了前ma

x(i,

j)個城市,因為兩個人的順序可以發生變化,我們令i≥

j 是不會影響狀態的。

但是該怎麼樣進行狀態轉移呢?注意到dp

[i][

j]表示他們已經走完了前i個城市,那為了保持定義,我們必須下乙個狀態走完前i+1個城市。但是由兩個人中的誰去呢?這個需要進行決策。

所以狀態轉移方程是: dp

[i][

j]=m

in(d

p[i+

1][j

]+d[

i][i

+1],

dp[i

+1][

i]+d

[j][

i+1]

),i≥

j 其中d[

i][j

] 表示第i個點和第j個點之間的距離。

邊界條件: dp

[n][

j]=d

[j][

n] 

演算法複雜度為θ(

n2).

**如下:

#include 

#include

#include

#include

using

namespace

std;

const

int max = 1010;

int x[max],y[max];

double d[max][max];

double dp[max][max];

int main(void)

d[i][i] = 0.0;

}for(int i = 1; i <= n; ++i)

dp[n][i] = d[i][n];

for(int i = n - 1; i >= 1; --i)

for(int j = 1; j <= i; ++j)

dp[i][j] = min(dp[i+1][j] + d[i][i+1],dp[i+1][i] + d[j][i+1]);

printf("%.2f\n",dp[1][1]);

}return

0;}

UVA 1347 Tour 記憶化搜尋dp

題意 見紫書 分析 可以看成兩個人一起走,dp i j 表示已經走過了max i,j 個點還剩多長距離到達最後的點,規定i走在j前面,走的時候只往下走max i,j 1的那個點即可,最後的狀態就是乙個人在第n 1個點,求出另乙個人在其他點時的最後所剩距離,然後dfs include include ...

uva1347(dp,雙調歐幾里得旅行商問題)

題意 給出n個點,確定一條連線各點的最短閉合旅程的問題。將其轉換成2個人同時從最左邊出發,然後分別經過不同路徑到達最右邊的距離 求解一般過程 1 首先將各點按照x座標從小到大排列,時間複雜度為o nlgn 2 尋找子結構 定義d i,j 為序號1 max i,j 已經全部被訪問過,並且當前位置在i和...

POJ 2677 Tour 雙調旅行商

題意 給你 n 個二維座標上的點,你需要經過所有的點然後走回原地,求最短路徑。思路 我們先給所有的點按照 x 座標公升序排列,因為要走成環我們可以看成兩個人同時從第乙個點開始走,定義 dp i k 表示第乙個人走到第 i 個點第二個人走到第 k 個點的最短距離 走在前面的人是 i 對於任意乙個點i來...