題意:
給出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...