最優配對問題(集合上的動態規劃) 狀壓DP

2021-08-01 09:51:22 字數 1220 閱讀 1930

題意:

給出n個點的空間座標(n為偶數, n<=20), 把他們配成n/2對, 問:怎樣配對才能使點對的距離和最小? 

題解:

設dp[s]為:狀態為s(s代表著某個子集)時, 它的最小距離和。

1.對於乙個狀態s, 首先要計算它減少兩個點後的狀態的最小距離和, 然後當前狀態才能從這些狀態中轉移過來。

2.如何轉移:對於狀態s, 在集合中隨便找乙個點,列舉集合中的其他點與它配對, 取距離和最小的那一對。

3.為什麼選定乙個點,然後列舉集合中的其他點就可以呢?而兩個點都要列舉呢? 因為:對於選定的點, 它總得要和集合中的其他點配對, 那麼答案就肯定蘊藏在某一次配對中了。而列舉兩個點, 實際上是多餘的。

實現:

1.遞推:自底向上,從最小的子集開始計算, 然後大的子集就可以從中轉移過來。缺點是點數為奇數的情況也考慮進去了(可以預先判斷點數是否為偶,以決定是否需要進入 計算), 速度慢。

2.記憶化搜尋:很好理解,對於狀態s, 假設它的偶數子集的最小距離和都計算出來了, 那麼選定某個點, 再列舉其他點就可以了。而且避免了奇數個元素的子集的計算。

遞推:#include #include #include using namespace std;

const int inf = 2e9;

const int maxn = 21;

struct nodedot[maxn];

int n;

double dp[1<> n;

for(int i = 0; i < n; i++)

cin >> dot[i].x >> dot[i].y >> dot[i].z;

solve();

cout << dp[(1<

記憶化搜尋:

#include #include #include using namespace std;

const int inf = 2e9;

const int maxn = 21;

struct nodedot[maxn];

int n;

double dp[1<> n;

for(int i = 0; i < n; i++)

cin >> dot[i].x >> dot[i].y >> dot[i].z;

dp[0] = 0;

for(int i = 1; i < (1<

集合上的動態規劃 最優配對問題

此部落格 題目 劉汝佳 演算法競賽入門經典 集合上的動態規劃 最優配對問題 題意 空間裡有n個點p0,p1,pn 1,你的任務是把它們配成n 2對 n是偶數 使得每個點恰好在乙個點對中。所有點對中兩點的距離之和應盡量小。狀態 d i,s 表示把前i個點中,位於集合s中的元素兩兩配對的最小距離和 狀態...

最優配對問題(動態規劃)

空間裡有n個點p0,p1,p2.pn 1,你的任務是把他們配成n 2對 n是偶數 使得每個點恰好在乙個點對中。所有點的距離之和應該盡量小。n 20.定義狀態d i s 為前i個點中,位於集合s的元素兩兩配對的最小距離,則狀態轉移方程就是 d i,s min 其中 pipj 表示兩點之間的距離。邊界是...

狀壓DP 最優配對問題(jzoj 3420)

在平面上有n個點,現在要把他們拼成n 2對,拼接兩個點的代價是他們的平面距離,現在問代價總和最小是多少 4 8730 9323 3374 3929 7890 6727 1257 468920366.602 n 20 用dfs每一次選1個數和當前數字匹配,如果當前數字選過了,就進入下一層 includ...