藍橋杯 擺動序列(步步講解,解密DP)

2021-10-24 20:22:00 字數 2829 閱讀 4425

問題描述】

如果乙個序列的奇數項都比前一項大,偶數項都比前一項小,則稱為乙個擺動序列。

即 a[2i]a[2i]。

小明想知道,長度為 m,每個數都是 1 到 n 之間的正整數的擺動序列一共有多少個。

【輸入格式】

輸入一行包含兩個整數 m,n。

【輸出格式】

輸出乙個整數,表示答案。答案可能很大,請輸出答案除以10000的餘數。

【樣例輸入】

3 4【樣例輸出】

14【樣例說明】

以下是符合要求的擺動序列:

2 1 2

2 1 3

2 1 4

3 1 2

3 1 3

3 1 4

3 2 3

3 2 4

4 1 2

4 1 3

4 1 4

4 2 3

4 2 4

4 3 4

【評測用例規模與約定】

對於 20% 的評測用例,1 <= n, m <= 5;

對於 50% 的評測用例,1 <= n, m <= 10;

對於 80% 的評測用例,1 <= n, m <= 100;

對於所有評測用例,1 <= n, m <= 1000。

如果當前項為奇數項,那麼當前項的取值一定要比前一項大,

如果當前項為偶數項,那麼當前項的取值一定要比前一項小。

由此我們可不可以理解為當前項的取值範圍

由前一項的取值範圍中的乙個值的大小決定。

而前一項的取值範圍又是由前二項取值範圍中的乙個值的大小決定的

建立二維陣列dp[i][j] 暫時摒棄二維陣列的概念,看下面對i,j,dp[i][j]的定義:

i:表示當前項的位置 本題範圍:1 <= m

j:表示取的值 本題範圍:1 <= n

可以理解為在i的位置放j

dp[i][j]:表示第i個位置,放j的時候,綜合在滿足前一項的基礎上,有dp[i][j]中放法

換句話說:就是如果我要在i位置放j那麼我是不是一定要符合前乙個位置的值的放法

注:因為第一項為奇數項,奇數項要比前一項大,但是第一項的前一項並不存在,所以

第一項的放法就沒有限制,1----n都可以放

所以dp[1][j]=1;

本題m = 3,n = 4為例:

建立dp[m+1][n+1]大小的二維陣列,從下標i=1到i=m放數

dp[1][1]=1 注:第乙個位置放1一種放法

dp[1][2]=1 注:第乙個位置放2一種放法

dp[1][3]=1 注:第乙個位置放3一種放法

dp[1][4]=1 注:第乙個位置放4一種放法

因為我們是動態遞推,所以要初始化,從第一項往後推

當前dp狀態

1 1 1 1

0 0 0 0

0 0 0 0

當i=2時,意味著在第二個位置放數,那i此時為偶數,那麼必須比前一項小

所以在i = 2的位置放1的話,是不是在i = 1的位置,放2 ,3,4的值都可以

那是不是

dp[2][1]=dp[1][2]+dp[1][3]+dp[1][4] 一共有3種呢?

同理:dp[2][2]=dp[1][3]+dp[1][4] 一共有2種呢?

dp[2][3]=dp[1][4] 一共有1種呢?

dp[2][4]=0 沒有符合條件的,組成2個序列的組合呢?

就意味著當m=2,n=4的時候

dp[2][1]+dp[2][2]+dp[2][3]+dp[2][4] 相加的結果就是m=2,n=4的結果呢?

但是我們本題求的是,m=3,n=4,那麼就在前一項的基礎上,向下遞推就行了

此時dp狀態

1 1 1 1

3 2 1 0

0 0 0 0

當i=3時,意味著在第三個位置放數,那i此時為奇數,那麼必須比前一項大

所以在i = 3的位置放1的話,是不是在i = 2的位置,只能放0呢? j的取值1 <= n不符合條件

那是不是

dp[3][1]=0 沒有符合條件的上一項

dp[3][2]=dp[2][1] 一共有3種呢?

dp[3][3]=dp[2][1]+dp[2][2] 一共有5種呢?

dp[3][4]=dp[2][1]+dp[2][2]+dp[2][3] 一共有6種呢?

就意味著當m=3,n=4的時候

dp[3][1]+dp[3][2]+dp[3][3]+dp[3][4] 相加的結果就是m=3,n=4的結果呢?

此時dp狀態

1 1 1 1

3 2 1 0

0 3 5 6

是不是很簡單:

那很容易獲得

i為偶數的時候的動態轉移方程(2<=i<=m)

dp[i][j]+=dp[i-1][k] (j+1 <= k <= n)

i為奇數的時候的動態轉移方程(2<=i<=m)

dp[i][j]+=dp[i-1][k] (1 <= k <= j-1)

#include

intconst n =

1010

;int

const m =

10000

;int m,n,i,j,k;

int dp [n]

[n];

int num;

using

namespace std;

intmain()

for(i=

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

}else}}

}for

(j=1

;j<=n;j++

) cout

}

藍橋杯 擺動序列

題目 問題描述 如果乙個序列滿足下面的性質,我們就將它稱為擺動序列 1.序列中的所有數都是不大於k的正整數 2.序列中至少有兩個數。3.序列中的數兩兩不相等 4.如果第i 1個數比第i 2個數大,則第i個數比第i 2個數小 如果第i 1個數比第i 2個數小,則第i個數比第i 2個數大。比如,當k 3...

藍橋杯 擺動序列 df

include include int a 100 擺動陣列 int vis 100 int k int ans bool judge int x,int index void dfs int count int main 問題描述 如果乙個序列滿足下面的性質,我們就將它稱為擺動序列 1.序列中的所...

藍橋杯 演算法訓練 擺動序列

演算法訓練 擺動序列 時間限制 1.0s 記憶體限制 512.0mb 提交此題 錦囊1 錦囊2 問題描述 如果乙個序列滿足下面的性質,我們就將它稱為擺動序列 1.序列中的所有數都是不大於k的正整數 2.序列中至少有兩個數。3.序列中的數兩兩不相等 4.如果第i 1個數比第i 2個數大,則第i個數比第...