回溯法複習(二)

2021-08-14 14:45:41 字數 1464 閱讀 6428

uva140

這是一道典型的回溯法題目,第一次做的時候並沒有做出來,在參考了網上的一些ac**後經過修改,終於ac成功了。

下面先附上**:

#include #include #include #include using namespace std;

const int maxn = 10;

char letter[maxn];

int id[256];

char str[100];

int p[maxn];

int pos[maxn];

int vis[maxn];

int n;

int bestp[maxn];

int bindwidth;

int bestw;

int g[maxn][maxn];

void dfs(int cur)

}for(int j = 0;j=bestw) ok = 0;

if(ok)

} }}

int main()

int len = strlen(str);

int t;

for(int i = 0;i%d\n",bestw);

} return 0;

}

首先這個題目的注意要點有以下幾個:

1)雙向對映的程式寫法,使用strchr函式進行letter和id陣列的賦值,而且進行了潛在的排序操作。

2)圖的表示,這裡我用了鄰接矩陣表示,便於進行剪枝的有關計算,這裡在dfs中進行了兩個剪枝的操作(根據書上的提示):

a)當當前訪問的節點位置cur與前面的位置,之間的頻寬大於等於當前最大頻寬,剪枝;

b)當與當前訪問節點相鄰的不確定的節點數量大於等於當前頻寬,剪枝。

網上的一些方法使用next_permutation()函式,在**規模上較小,但是在剪枝情況上不如直接通過dfs回溯方法操作的好。當然這對演算法的正確性並沒有影響,但是作為訓練,我依然使用了這種dfs的方法。

uva1354

#include #include #include #include using namespace std;

const int n = 6;

const int maxn = 1int vis[maxn];

int bitcount(int x)

void dfs(int u)

for (int l = (u - 1)&u; l > 0; l = (l - 1)&u) //列舉二叉樹的子樹

} }

}double solve()

{ int root = (1<

1)二進位制方法列舉子集

2)對樹的節點構建乙個表,每一行對應乙個節點集合,每個元素對應每種情況下的左右節點。

3)二進位制列舉二叉樹的子樹

以上兩個題目的解答方法都借鑑了一些網上的解法,但在很多細節處與網上的**有所不同。

回溯法,回溯法解裝載問題

利用回溯法解問題時一般按以下三步驟 1 定義問題的解空間 2 確定易於搜尋的解空間結構 3 以深度優先策略搜尋解空間,並在搜尋過程中用剪枝函式避免無效搜尋 二 回溯法應用 裝載問題 一批貨櫃共n個要裝上2艘載重量分別為c1和c2的輪船,其中貨櫃i的重量為wi且w1 w2 wn c1 c2 試確定乙個...

演算法分析之回溯法二

2.整數變換問題 整數i的兩種變換定義為,向下取整 設計乙個演算法求給定兩個整數a和b,用最少次數的和變換將整數a變換為b 例如 題目分析 觀察f和g兩個函式發現,f總是使得自變數x變大,g總是使得自變數x變小。因此我們在決定讓x執行哪個函式之前必須先判斷x和目標值m之間的大小關係。如果x m,就讓...

回溯法 回溯法介紹 回溯與遞迴的區別

回溯法 有一類問題,我們不知道它明確的計算法則。而是先進行試探,試探到最終狀況,發現不滿足問題的要求,則回溯到上乙個狀態繼續試探。這種不斷試探和回溯的思想,稱為回溯法 backtrcking 此類問題包括 求最優解 一組解 全部解。例如八皇后問題 回溯的演算法思想 一直往下走,然後再一步步往回走 面...