7-2 子集和問題 (20分)
7-3 馬周遊問題 (60分)
返回主目錄
圖k-著色問題是乙個著名的np完全問題。給定無向圖g=(v,e)和正整數k,問可否用k種顏色為v中的每個結點分配一種顏色,使得不會有兩個相鄰結點具有同一種顏色? 該問題的乙個具體例項可能會有多個解(乙個解就是一種合法的著色方案),要求計算全部解的數目。
輸入格式:
輸入的第一行包含三個整數n(1≤n≤20)、m(0≤m≤n(n−1)/2)和k(1≤k≤n),分別是無向圖的結點數、邊數和可用顏色數。 結點從1到n編號,顏色從1到k編號。隨後m行,每行給出一條邊的兩個端點的編號。題目保證給定的無向圖是簡單圖(即不存在自環和多重邊)。
輸出格式:
輸出一行表示全部解的數目(無解時輸出0即可)。
輸入樣例:
5 7 3
1 22 3
3 44 5
5 11 3
1 4輸出樣例:
6
#include
using namespace std;
int n, m, k;
int ans =0;
//number of results
vector
int>
> table;
vector<
int> colorofpoint;
bool islegal
(int point)
}return true;
}void
kcolor
(int point)
for(
int color =
1; color <= k; color++
) colorofpoint[point]=0
;//無論進入下乙個點還是非合法塗色,都應在這裡清零}}
intmain()
}for
(int i =
1; i <= n; i++
)int tmps, tmpe;
for(
int i =
0; i < m; i++
)kcolor(1
);//從第乙個點開始
cout << ans;
return0;
}
子集和問題是乙個典型的np難度問題。給定乙個正整數集合a=(元素互不相同)和乙個正整數y,問是否存在乙個子集y⊆a,它的元素之和為y? 該問題的乙個具體例項可能會有多個解(乙個解就是乙個元素之和為y的子集y⊆a),要求計算並輸出某個特定的解。
輸入格式:
輸入的第一行包含兩個整數n(1≤n≤20)和y(>0),分別是集合a的元素個數和子集和的目標值,a的元素從1到n編號。 接下來的一行有n個數,表示集合a的n個元素。最後乙個行是乙個正整數t,表示待計算並輸出的第t個解。注意,如果將集合中元素由小到大排序,則問題的所有解有字典序。這裡要求輸出按字典序的第t個解。題目保證集合a的元素互不相同且按照遞增次序輸入。
輸出格式:
輸出佔一行, 表示按字典序的第t個解,解中各個數遞增且兩數之間用一空格隔開。若第t個解不存在,則輸出"no solution!"。
輸入樣例:
6 60
10 20 30 50 60 80
2輸出樣例:
10 50
(這裡所有的解按照字典序依次為、、,第2個解為)
#include
using namespace std;
int n, y, t;
vector<
int> num;
vector boolvec;
vector
> ans;
//本程式的思想是通過用布林向量標註符合y的數字,比如10,20,30的向量就是
//num儲存輸入數字,boolvec用來標註當前的布林向量情況,ans用於儲存符合要求的布林向量
void
getallboolvec
(int index,
int sum)
else
if(sum == y)
/*else */
boolvec[index]=0
;//將之前操作取消,進入右子樹,相當於回溯
sum -
= num[index]
;getallboolvec
(index +
1, sum)
;//與前面呼應從而形成左右子樹(實際上還是陣列資料結構)
}void
output
(vector boolvector)
else}}
}int
main()
cin >> t;
getallboolvec(0
,0);
if(t > ans.
size()
)else
return0;
}
如果在n較大t較大的測試點過不了,我提供乙個sample
輸入:任給大小為n×n(8≤n≤1000)的棋盤, 在棋盤上任意設定馬的初始位置,試快速找出一種馬能跳到每個棋格恰好一次的棋步(要求最後回到初始位置)。注意,棋盤上馬按照跳「日」的規則移動。例如,在8×8的棋盤, 當馬位於第3行第4列的方格時,下一步可以跳到箭頭所指的八個方格之一。10 10
1 2 3 4 5 6 7 8 9 10
10輸出:
10
輸入格式:
在一行中給出三個正整數n,a,b,其中n(8≤n≤1000)為棋盤的行列大小, a和b(1≤a,b≤n)分別是馬的初始位置所在方格的行號和列號。
輸出格式:
輸出佔n行,每行含有n個正整數,組成乙個n× n方陣。該方陣的n
2 個元素由正整數1,2,…,n
2 組成,其中馬走第i步前所處方格其內對應的數為i(i=1,2,…,n
2 ) (馬在初始位置所處方格內數為1)。
輸入樣例:
8 3 4
輸出樣例:
54 57 44 25 64 59 42 9
45 2 55 58 43 8 63 60
56 53 24 1 26 61 10 41
3 46 19 28 21 12 7 62
52 29 4 23 6 27 40 11
47 18 49 20 13 22 37 34
30 51 16 5 32 35 14 39
17 48 31 50 15 38 33 36
這道題我用自己的方法老是超時失敗,我在網上找到了乙個通過的,但是該**風格實在一言難盡。。所以這裡就貼一下吧。注釋掉的就是能通過的。。網上也有寫成專案形式的解題方法。
更新:目前找到了一種思路,待有時間實現看看。
更新:請參考這篇博文,下面先給出他的**。
#include
#include
#include
#include
using namespace std;
typedef
struct
step;
step step[8]
=,,,
,,,,
};struct nextpos };
int board[
100]
[100];
int m,n;
//棋盤大小
//檢測這個位置是否可以走
bool check
(int x,
int y)
//下一位置有多少種走法
intnextposhassteps
(int x,
int y)
return steps;
}//判斷是否回到起點
bool returnstart
(int x,
int y)
//輸出結果
void
outputresult
(int xstart,
int ystart)
} cout<
}//某一位置距離棋盤中心的距離
intpostomidlength
(int x,
int y)
void
backtrace
(int t,
int x,
int y,
int xstart,
int ystart)
else
}while
(nextposqueue.
size()
)}}void
horserun
(int xstart,
int ystart)
intmain()
作業分配(回溯法)
有n份作業分配給n個人去完成,每人完成乙份作業。假定第i個人完成第j份作業需要花費cij時間,cij 0,1 i,j n。試設計乙個回溯演算法,將n份作業分配給n個人完成,使得總花費時間最短。c 實現 author qinwu created time 2017 4 30 22 45 25 file...
回溯法 批處理作業排程 回溯演算法 批處理作業排程
成為該作業排程的完成時間和。批處理作業排程問題要求對於給定的 n個作業 制定乙個最佳的作業排程方案 使其完成時間和達到最小。批處理作業排程問題的乙個常見例子是在計算機系統中完成一批 n個作業,每個作業都要完成先計算,然 後將計算機結果列印輸出這兩項任務 計算任務由計算機的 處理器完成 列印輸出任務由...
演算法 回溯法
0.0 回溯法核心 go depth begin from go 0 1.0 八皇后問題 問題描述 將八位皇后放在一張8x8的棋盤上,使得即任意兩個皇后都不在同一條橫線,豎線和斜線上,問一共有多少種擺法?暴力窮舉 step 1 先不考慮對稱性和可行性,一共是c 8 64 c tbinom c 648...