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 此類問題包括 求最優解 一組解 全部解。例如八皇后問題 回溯的演算法思想 一直往下走,然後再一步步往回走 面...