滿足如下條件的序列x(序列中元素被標號為1、2、3…m)被稱為「加成序列」:
1、x[1]=1
2、x[m]=n
3、x[1]4、對於每個 k
'>k
k(2≤k≤
m'>2≤k≤m
2≤k≤m)都存在兩個整數 i
'>i
i 和 j
'>j
j (1≤i
,j≤k
−1'>1≤i,j≤k−1
1≤i,j≤k−1,i
'>i
i 和 j
'>j
j 可相等),使得x[k]=x[i]+x[j]。
你的任務是:給定乙個整數n,找出符合上述條件的長度m最小的「加成序列」。
如果有多個滿足要求的答案,只需要找出任意乙個可行解。
輸入格式
輸入包含多組測試用例。
每組測試用例佔據一行,包含乙個整數n。
當輸入為單行的0時,表示輸入結束。
輸出格式
對於每個測試用例,輸出乙個滿足需求的整數序列,數字之間用空格隔開。
每個輸出佔一行。
深度優先搜尋(dfs)每次選取乙個分支, 不斷深入, 直到到達遞迴邊界才回溯, 但這種策略有一定的缺陷, 假如搜尋樹每個節點的分支數目從非常多, 並且問題的答案在某個較淺的節點上。如果一開始就選錯了分支, 就很可能在不包含答案的深層子樹上浪費許多時間;所以限制每次限制搜尋的深度d, 多次搜尋, 這和重複搜尋與深層子樹的規模來比, 實在是小巫見大巫了;
這道題可以看出, m的規模不會太大(<=10),所以我們用迭代加深的搜尋方式, 從1開始限制深度, 若搜尋失敗就增加深度限制重新搜尋, 直到找到一組解為止;
#include usingnamespace
std;
typedef
long
long
ll;const
int inf = 0x3f3f3f3f
;const
int maxn = 2e6 + 100
;const
int maxm = 3e3 + 10
;template
< typename t > inline void read(t &x)
while
(isdigit(ch))
x *=ff;
}template
< typename t > inline void
write(t x)
intn, a[maxn];
bool
vis[maxn];
int dfs(int now, int deep, int
val)
else
if(a[i] + a[j] <= val) break
; }
}return0;
}int
main()
for(int i = 2; i <= 10; ++i)
puts(
"");
break
; } }}
return0;
}
AcWing 170 加成序列
給定乙個數字生成乙個序列要使得序列中的元素滿足遞增且每個數都能用他前面的兩個數 可以是乙個數的兩倍 相加得到。第乙個數和第二個數肯定是1和2,然後再根據層數和數要遞增這些限制來進行dfs。include using namespace std typedef long long ll const i...
AcWing 170 加成序列(搜尋)
原題鏈結 感悟 之前用紫書學了下迭代加深,自我感覺應該還是可以的,這次在來實踐的時候才發現,除了知道大概要怎麼做外,其他的全無頭緒。很難受。這道題還是簡單題啊!從這道題開始總結經驗吧,還有老師講的很好啊。題型基本框架 本題思路 accode include include using namespa...
迭代加深 索道
這天,tom帶一群小朋友們去爬山。經歷了千辛萬苦,小朋友們終於爬上了山頂,但是疲倦的他們再也不想徒步走下山了。tom只好花錢讓它們坐索道下山。索道上的纜車最大承重量為w,而n個小朋友的重量分別是c1 c2 cn。當然,每輛纜車上的小朋友的重量之和不能超過w。每租用一輛纜車,tom就要付1美元,所以他...