問題描述
如果乙個序列滿足下面的性質,我們就將它稱為擺動序列:
1. 序列中的所有數都是不大於k的正整數;
2. 序列中至少有兩個數。
3. 序列中的數兩兩不相等;
4. 如果第i – 1個數比第i – 2個數大,則第i個數比第i – 2個數小;如果第i – 1個數比第i – 2個數小,則第i個數比第i – 2個數大。
比如,當k = 3時,有下面幾個這樣的序列:
1 21 3
2 12 1 3
2 32 3 1
3 13 2
一共有8種,給定k,請求出滿足上面要求的序列的個數。
輸入格式
輸入包含了乙個整數k。(k<=20)
輸出格式
輸出乙個整數,表示滿足要求的序列個數。
樣例輸入
3樣例輸出
自己從來沒有做過動態規劃的題目,之前接觸動態規劃還是為了過演算法的考試。所以說,坑總是要填的,遲早的事情,加油!
言歸正傳,這個題是要求滿足題目的序列個數。剛開始看到這個題,我的想法是,先自己試著手動做做,看看能不能發現什麼。果然被我試出來了。動態規劃核心是構造乙個表,根據已有的**內容得到我們想要的結果。構造表的過程並不是一下子就成功的,期間我共想了兩種方式來構造,但是後來發現第一種方式是沒有辦法構造表的,因為在構造的過程中發現表間元素沒有什麼關聯,所以換個思路,用另乙個方法進行構造(有點遞迴的意思,但是並不是遞迴,也就是說當前資料依靠**的之前的資料),給大家看一下我的**構造:
擺動串行動規**
002003
004005
006007
00800220
0000
000362
0000
0004128
2000
0005
2020102
000006
3040
301220
0007
4270
7042142
0008
56112
140112
5616
2通過這個**不難發現規律。
(1)這個**為什麼從2開始呢?
因為根據題目要求,每行至少兩個正整數,所以不存在0和1的情況;
(2)這個**根據什麼構成?
是根據k值的不同,來看對應情況下的可能的序列個數。舉個例子:當k等於3的時候,考慮如果只有倆個數組成,可能多少種情況,如果有3個數組成,可能多少種情況。填入到**中即可。如果學過排列組合,那不難發現彼此之間的關係,也因此得到了這個**。
(3)有人可能通過排列組合的方式,不用構建**就可以得到最後的結果,那還有必要建**嗎?
有必要。如果是排列組合,舉例來說:k=8時,
這樣也可以算出最後的結果,但是乘法比加法的運算速度慢,此外,如果這麼計算,其實重複性挺大的,利用**,相當於記錄了路徑,之前算的東西可以直接拿來用,不用重新進行計算,更為快捷方便!
#includeusing namespace std;
int main()
} for(int i = 2; i <= k; i++)
cout<
end。
ALGO 12 演算法訓練 冪方分解
演算法訓練 冪方分解 時間限制 1.0s 記憶體限制 256.0mb 問題描述 任何乙個正整數都可以用2的冪次方表示。例如 137 27 23 20 同時約定方次用括號來表示,即ab 可表示為a b 由此可知,137可表示為 2 7 2 3 2 0 進一步 7 22 2 20 21用2表示 3 2 ...
藍橋杯 ALGO 83 演算法訓練 階乘
問題描述 乙個整數n的階乘可以寫成n 它表示從1到n這n個整數的乘積。階乘的增長速度非常快,例如,13 就已經比較大了,已經無法存放在乙個整型變數中 而35 就更大了,它已經無法存放在乙個浮點型變數中。因此,當n比較大時,去計算n 是非常困難的。幸運的是,在本題中,我們的任務不是去計算n 而是去計算...
藍橋杯 ALGO 33 演算法訓練 數列
演算法訓練 數列 時間限制 1.0s 記憶體限制 256.0mb 問題描述 給定乙個正整數k 3 k 15 把所有k的方冪及所有有限個互不相等的k的方冪之和構成乙個遞增的序列,例如,當k 3時,這個序列是 1,3,4,9,10,12,13,該序列實際上就是 30,31,30 31,32,30 32,...