回溯法是一種試探的方法,從一條路走,能進則進,不能則退。
例如:在數字1、2、3…9(順序不變)之間插入 「+」, 「-」 或什麼都不插入,使得結果為100。
#include
using
namespace std;
#define n 8
//8個符號
int a=
;int num =0;
//計算滿足條件的式子的個數
char op[n]
;//符號
void
fun(
int sum,
int preadd,
int i)
cout<<
"=100"
<
}return;}
op[i]
='+'
; sum +
= a[i+1]
;fun
(sum,a[i+1]
,i+1);
//下乙個
sum -
= a[i+1]
;//回溯
op[i]
='-'
; sum -
= a[i+1]
;fun
(sum,
-a[i+1]
,i+1);
sum +
= a[i+1]
; op[i]
=' '
;int tmp;
if(preadd>0)
tmp = preadd *
10+ a[i+1]
;else
tmp = preadd *
10- a[i+1]
;fun
(sum-preadd+tmp,tmp,i+1)
;//下乙個
}int
main()
回溯法 0-1 揹包:當前物品是否能放,放了是否為最優。
物品總數為 n,物品重量為 weight[i],物品價值為 value[i],揹包總容量為c,求能放入揹包中物品的最大價值。
構建解空間樹:
//物品個數
#define c 6
//揹包容量
int w=
;//物品重量
int v=
;//物品價值
int x[n+1]
;int bestv =0;
void
dfs(
int i,
int cw,
int cv,
int op)
}else
}int
main()
活動安排問題:有乙個需要使用某一資源的n個活動集合 s ,s = 。該資源無論何時都只能同時被乙個活動占用,活動 i 有乙個開始時間 bi 和結束時間 ei (bi= ej 或 bj >= ei ,則兩個活動相容,現求一種最優活動安排方案,使得所有安排是活動個數最多。開始時間 bi = ,結束時間 ei = 。
#include
using
namespace std;
#define max 51
struct action
;int n =4;
action a=
,,,,
};//int x[max]
;//存放解向量
int bestx[max]
;//最優解向量
int last =0;
//乙個方案中相容活動的結束時間
int sum =0;
//乙個方案中相容活動個數
int bestsum =0;
//最優方案中的相容活動個數
void
swap
(int
&x,int
&y)void
showresult()
} cout<<
"活動安排個數:"
<
}void
dfs(
int i)
}else
dfs(i+1)
;//下乙個
swap
(x[i]
,x[j]);
sum = sum1;
last = last1;
//回溯}}
}int
main()
迷宮問題:用2表示牆,0表示路,1表示走過的路徑,本題採用深度優先的演算法從入口到出口。在每個位置都應該考慮從上下左右四個方向進行試探,若為通路,則將起改為1繼續試探,若為死路則依次回溯,將走過的1改回0。
#include
using
namespace std;
#define n 8
int maze[n]
[n]=,,
,,,,
,};int h[4]
=;//水平偏移量
int v[4]
=;//垂直偏移量
void
showpath()
}void
dfs(
int x,
int y)
else}}
}int
main()
超市找零錢:貪心演算法的找零錢問題要求找出去的紙幣數量最小,那就要依次找出最大的零錢。
#include
using
namespace std;
#define n 5
int a=
;int x[n]=;
//記錄解
int sum =0;
//零錢總個數
//獲取需找的零錢
intgetchange
(int
&price,
int&money)
void
change
(int change)
else
if(change>=50)
else
if(change>=20)
else
if(change>=5)
else}}
intmain()
getchar()
;getchar()
;return0;
}
動態規劃的關鍵是根據遞推關係填表,找到了子問題間的遞推關係就可以解決問題。
整數拆分問題:
#include
using
namespace std;
#define maxn 500
//整數拆分問題:
//整數n拆分為最多不超過k的整數
int dp[maxn]
[maxn]
;void
split
(int n,
int k)}}
intmain()
0-1揹包:
#define n 5
//物品個數
#define c 10
//物品容量
int wi=
;int vi=
;int value[n+1]
[c+1]=
;void
table()
}}}int s[n]=;
void
getselected
(int n,
int c)
getselected
(--n,c)
;//前乙個物品
}int
getvalue
(int n,
int c)
intmain()
cout<<
"該題的最大價值:"
<
cout<<
getvalue(5
,10)<
getselected(5
,10);
for(
int i=
0;i)//選擇的物品情況
cout<
<<
" ";
//0 1 1 0 1 即重量為 2+3+3 價值為 5+6+8
getchar()
;return0;
}
fibnacci序列
#include
using
namespace std;
#define n 8
int fib[
101]
;//下標0不使用
intfib
(int n)
intmain()
演算法課程期末複習總結
八大排序演算法複雜度比較 求解遞迴式的複雜度 max sum 最大子段和 int len arr.length int dp newint len 1 dp 0 0 for int i 1 i len i int res integer.min value for int i 1 i dp.leng...
演算法分析(期末複習版)
如果存在兩個正常數c和n0,對於所有的n n0,有 f n c g n 則記作 f n o g n o f n o g n o max f n g n o f n o g n o f n g n o f n o g n o f n g n 如果g n o f n 則o f n o g n o f n...
大二演算法期末複習 排序 英文姓名排序
time limit 1000 1000ms c others memory limit 65536 65536kb c others problem description 在漢語裡,對漢語姓名可以按拼音排序,也可以按筆畫順序排序。在英語裡,對英語姓名主要按字母順序排序。本題要求給定的一組英文姓名...