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

2021-08-17 04:38:13 字數 1249 閱讀 9907

題意:給出n個點,確定一條連線各點的最短閉合旅程的問題。(將其轉換成2個人同時從最左邊出發,然後分別經過不同路徑到達最右邊的距離)

求解一般過程:

(1)首先將各點按照x座標從小到大排列,時間複雜度為o(nlgn)。

(2)尋找子結構:定義d(i,j)為序號1~max(i,j)已經全部被訪問過,並且當前位置在i和j。(規定i>=j,等於當且僅當在最左和最右時取到)同時,定義dis(i,j)為點pi到pj之間的直線距離。

(3)最優解:我們需要求的是d(1,1)。

注意:為了不遺漏情況,並方便理解,規定一次只能有乙個人進行移動,且每次都會有乙個人走到i+1這個位置,不管這個是走的快的那個人還是走的慢的那個人。假如是走的快的那個人走到了i+1這個位置,那就是由d(i,j)這個位置轉移到了d(i+1,j)這個位置,以為後面位於j這個位置的人並沒有移動,所以是d(i,j)。相反,如果這時是後面那個人(本來位置是j)移動到了i+1這個位置,那麼本來位於i位置的人就不能移動了,那麼就轉變為了d(i+1,i)這個狀態。

其餘內容**解釋:

#include 

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define eps 1e-8

#define pi 3.1415

typedef

long

long ll;

using

namespace

std;

int n;

struct node//結構體儲存每個點的位置座標

e[1005];

double dp[1004][1004];//dp[i][j]表示兩個人分別位於i和j位置時,還離目標的距離

double dis[1005][1005];

double solve(int i,int j)

dp[i][j]=min(solve(i+1,j)+dis[i][i+1],solve(i+1,i)+dis[j][i+1]);//核心語句,

return dp[i][j];

}int main()

}printf("%.2lf\n",solve(1,1));

}return

0; }

UVA 1347 Tour 雙調旅行商

題意 平面上有n個點。乙個人要從左上角的點向右走,到右下角的點,然後再回到左上角的點。現在想讓這個人每個點到達一次,且走的總路程的距離最小。求出最小的距離。思路 雙調旅行商問題。因為起點和中途點已知,我們可以把這個問題轉化成兩個人從左上角出發,分別不重複的到達其他點,最後在右下角的點匯合。可以注意到...

歐幾里得旅行商問題uva1347

題意 自見紫書 題解 這道題啊,我發誓我是聽過的,但是我忘了,然後自己盯著這道題想了好久,也沒想出來 dp這東西,定義狀態是非常重要的啊,發現自己對這道題的狀態完全下不去手 有兩種分析思路 第一種是,設f i j 表示前i個點已經訪問過,落後的人在j時經過的最小路程 這是已經把來回看做兩個人 規定i...

UVa 1347 雙線程DP Tour

題意 平面上有n個座標均為正數的點,按照x座標從小到大一次給出。求一條最短路線,從最左邊的點出發到最右邊的點,再回到最左邊的點。除了第乙個和最右乙個點其他點恰好只經過一次。分析 可以等效為兩個人從第乙個點出發,沿不同的路徑走到最右點。d i,j 表示點1 max i,j 這些點全部都走過,而且兩人的...