本題的難點主要在於狀態的定義,即如何去表示節點的狀態。
在紫書中,作者選擇了dp(i,j)來表示第乙個人走到了i點,第二個人走到了j點,且編號小於max(i,j)的節點都被走過。因為dp[i][j]和dp[j][i]是重複的,因此規定i>j。這樣可以保證無後效性,因為小於max(i,j)的點都被選過了,接下來就是在大於max(i,j)裡面選點,所以之後的狀態不會影響到前面的狀態。
接下來考慮狀態如何轉移,由於狀態的定義,下一步只能向編號大於i的節點移動,那麼可以是第乙個人向前走一步,或者第二個人向前走一步。從而得到狀態轉移方程:
dp[i][j]=min(dp[i+1][j]+dist(i,i+1),dp[i+1][i]+dist(j,i+1)),其中dist表示兩點間的歐幾里得距離。
遞迴起點是dp[2][1]。遞迴邊界時dp[n-1][j],因為此時只剩下最後乙個點沒有經過,且dp[n-1][j]=dist(n-1,n)+dist(j,n)。
自然,ans=dp[2][1]+dist(1,2)。時間複雜度o為(n2)
#include
using
namespace std;
const
int inf=
0x3f3f3f3f
;int n;
int x[
1005];
int y[
1005];
double dp[
1005][
1005];
double
dist
(int a,
int b)
doubled(
int i,
int j)
void
solve
(void
)//對於dp[i][j],規定i>j
intmain
(void
)// fclose(stdout);
}//3
//1 1
//2 3
//3 1
//4//1 1
//2 3
//3 1
//4 2
UVa 1347 雙線程DP Tour
題意 平面上有n個座標均為正數的點,按照x座標從小到大一次給出。求一條最短路線,從最左邊的點出發到最右邊的點,再回到最左邊的點。除了第乙個和最右乙個點其他點恰好只經過一次。分析 可以等效為兩個人從第乙個點出發,沿不同的路徑走到最右點。d i,j 表示點1 max i,j 這些點全部都走過,而且兩人的...
UVA 1347 Tour 雙調旅行商
題意 平面上有n個點。乙個人要從左上角的點向右走,到右下角的點,然後再回到左上角的點。現在想讓這個人每個點到達一次,且走的總路程的距離最小。求出最小的距離。思路 雙調旅行商問題。因為起點和中途點已知,我們可以把這個問題轉化成兩個人從左上角出發,分別不重複的到達其他點,最後在右下角的點匯合。可以注意到...
UVA 1347 Tour 記憶化搜尋dp
題意 見紫書 分析 可以看成兩個人一起走,dp i j 表示已經走過了max i,j 個點還剩多長距離到達最後的點,規定i走在j前面,走的時候只往下走max i,j 1的那個點即可,最後的狀態就是乙個人在第n 1個點,求出另乙個人在其他點時的最後所剩距離,然後dfs include include ...