題意:平面上有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來...