期末複習之深搜

2021-10-07 07:18:56 字數 3579 閱讀 4304

1.張三丰的傳人

描述

張三丰憑藉太極拳成為一代宗師;然而歲月不饒人,他希望找到傳人,在有生之年將太極拳傳於**發揚光大。然而,張三丰的太極拳有乙個特點,學的時間越長,忘記的越多。乙個**學習時間為t,那麼他只可以學習到總功力的1/t。假設張三丰計畫用s的時間,他可以培養n個**,雖然可能每個**都無法完全學會,但是只要這n個**的總功力之和為1,張三丰就可以將s的時間,分配給這n個**,來完成自己的心願;如果給定s之後,對於任何的n,都無法找到一種有效的分配方案,張三丰只能含恨而終。在這裡,s,n和t均必須為正整數。

你的任務是:給定整數s,幫助張三丰找出乙個整數n,以及乙個分配方案。例如:s為10時,你幫助張三丰找到3個**,傳授他們武功的時間分別為;s為2時,你無論如何無法找到這樣乙個方案,張三丰只能含恨而終。

輸入

第一行是乙個正整數m,表示測試資料的組數。

每組測試資料只有一行,乙個正整數s( 1<=s<65536),表示張三丰計畫傳授太極拳的總時間。

輸出

對每組測試資料:如果你可以幫助張三丰找到這樣一組方案,首先輸出正整數n,然後輸出n個數分別代表分配給這n個**各自的時間,資料之間用空格隔開;如果你無法找到這樣的分配方案,輸出-1.

樣例輸入31

210樣例輸出

1 1-1

3 2 4 4

提示

注意:這樣的方案可能有多組,你只需要輸出任何一組;另外,本題目中浮點數的精度控制在1e-6.

思路:1.可行性剪枝

2.輸出時由小到大,因此int i = x; i <= left; ++i這樣美劇,縮小搜尋範圍

3.sum是double型別就過了,float會tle。why???

#include

#include

using

namespace std;

int s;

bool flag =0;

vector<

int>memo;

double sum =0;

void

dfs(

int left,

int x)

if(sum >

1|| left <=1)

return;if

(sum +

1.0/left >

1.0+

1e-6

)return

;for

(int i = x; i <= left;

++i)

}int

main()

dfs(s,2)

;if(!flag)

cout <<-1

<< endl;

memo.

clear()

; sum =0;

}return0;

}

2.忍者道具

描述

忍者道具有很多種,苦無,飛鏢,震爆彈。l君熱衷於收集忍者道具,現在他有n個道具,每個道具的重量分別是c1、c2…cn。現在他想把這n個道具裝到載重量為w的工具包裡,請問他最少需要多少個工具包?

輸入

第一行包含兩個用空格隔開的整數,n和w。

接下來n行每行乙個整數,其中第i+1行的整數表示第i個道具的重量ci。

輸出

輸出乙個整數,最少需要多少個工具包。

樣例輸入

5 199612

1994

1229

樣例輸出

2提示

對於100%的資料,1<=n<=18,1<=ci<=w<=10^8。

#include

#include

using

namespace std;

int n, w;

int item[20]

;int ans =21;

int cab[20]

;void

dfs(

int cnt,

int now)

for(

int i =

1; i <= cnt; i++)}

cab[cnt+1]

= item[now]

;dfs

(cnt+

1, now+1)

; cab[cnt+1]

=0;}

intmain()

3.課程表

描述

現在你總共有n門課需要選,記為0到n-1。在選修某些課程之前需要一些先修課程。例如,想要學習課程0,你需要先完成課程1,我們用乙個匹配來表示他們:[0, 1]。給定課程總量以及它們的先決條件,判斷是否可能完成所有課程的學習?

輸入

多組資料。每組資料第一行是n和m,n表示有n門課程,m表示有m組依賴關係,接下來的m行是依賴關係的具體資訊a b,表示第a門課程依賴第b門課程。

0<=n <=1000,0 <= m <= 4000

兩組資料之間可能有空行

輸出

對每組資料,能完成輸出 true,不能完成輸出 false

樣例輸入

2 11 0

2 21 0

0 1樣例輸出

true

false

提示

示例2解釋: 總共有2門課程。學習課程1之前,你需要先完成課程0;並且學習課程0之前,你還應先完成課程1。這是不可能的。

思路見注釋

#include

#include

using

namespace std;

using

namespace std;

int m,n;

int visited[

1005]=

;vector<

int>q[

1005]=

;bool

dfs(

int i)

visited[i]=1

;return

true;}

intmain()

for(

int i =

0; i < m;

++i)

for(

int i =

0; i < n;

++i)}if

(flag)

cout <<

"true"

<< endl;

}return0;

}

排列組合 深搜專題複習

有n種物品,並且知道每種物品的數量。要求從中選出m件物品的排列數。例如有兩種物品a,b,並且數量都是1,從中選2件物品,則排列有 ab ba 兩種。input 每組輸入資料有兩行,第一行是二個數n,m 1 m,n 10 表示物品數,第二行有n個數,分別表示這n件物品的數量。output 對應每組資料...

期末複習之寬度優先搜尋

寬度優先搜尋的演算法思想是比較簡單了 關鍵就是如何在有限的時間內寫出正確的寬度優先搜尋才是重點 不過在開始還是要弄明白,看到乙個題,到底是用寬度優先搜尋還是用深度優先搜尋,所以,我們要明白寬度優先搜尋相對於深度優先搜尋的優點 1.方便找到最優解 一般第乙個解就是最優的,而深度優先搜尋必須要遍歷完所有...

廣搜和深搜

一般來說,廣搜常用於找單一的最短路線,或者是規模小的路徑搜尋,它的特點是 搜到就是最優解 而深搜用於找多個解或者是 步數 已知 好比3步就必需達到前提 的標題,它的空間效率高,然則找到的不必定是最優解,必需記實並完成全數搜尋,故一般情況下,深搜需要很是高效的剪枝 優化 像搜尋最短路徑這些的很顯著若是...