題目
問題描述
如果乙個序列的奇數項都比前一項大,偶數項都比前一項小,則稱為乙個擺動序列。即 a[2i]a[2i]。
小明想知道,長度為 m,每個數都是 1 到 n 之間的正整數的擺動序列一共有多少個。
輸入格式
輸入一行包含兩個整數 m,n。
輸出格式
輸出乙個整數,表示答案。答案可能很大,請輸出答案除以10000的餘數。
樣例輸入
3 4樣例輸出
樣例說明
以下是符合要求的擺動序列:
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。
這道題我看網上很多大佬的解法都很巧妙,我這裡分享一下我對這道題的解法,這道題暴力求解肯定不能通過所有的結點。所以時要用到動態規劃的思想。
首先假設d[i][j]為第i列中以j結尾的方案總數。
此時有兩種情況。
1.當i是奇數時,這時如果以j結尾說明它前面一位數的值一定小於j所以方案數就為前面一行所有以小於j結尾的方案數。
即 d[i][j]=sum(d[i-1][1]+…+d[i-1][j-1]);
2.當i是偶數時,這時如果以j結尾說明它前面一位數的值一定大於j所以方案數就為前面一行所有以大於j結尾的方案數。
即 d[i][j]=sum(d[i-1][n]+…+d[i-1][j+1]);
此時我們很容易就寫出了動態規劃的基礎**
//動態規劃解
#include
#include
#include
#include
#include
#include
#define maxn 1000005
#define pi 10000
using
namespace std;
int m,n;
int dp[
1005][
1005];
//記錄,表示第i列以j數字結尾的總數 時間複雜度o(n^3
intmain()
for(
int i=
2;i<=m;i++)}
}if(i%2==1
)}}}
long sum=0;
for(
int i=
1;i<=n;i++
) cout
}
可是此時的時間複雜都依然達到了o(n^3),顯然不能全部通過此題,
於是要進行**的優化,我們觀察奇數列d[i][j]=sum(d[i-1][1]+…+d[i-1][j-1]);
可知,等式右邊不就等於前面一列小於j結尾的方案數的和嘛,這就相當於1-(j-1)的字首和。
於是我們可以重新考慮狀態轉移方程
用dp1[i][j]表示第奇數列以從1 — j 的方案數的字首和;
用dp2[i][j]表示第偶數列以從1 — j 的方案數的字首和;
奇數列有如下的狀態轉移
dp1[i][j]=dp2[i-1][j-1]+dp1[i][j-1];
解釋:dp1[i][j]分為兩個部分,乙個就是1—(j-1)的字首和加上以j結尾的所有方案數,而以j結尾的方案數顯然等於前一列所有小於j-1的方案數即前一列1-(j-1)的字首和即dp2[i-1][j-1]。
偶數列同樣分析有,
dp2[i][j]=dp1[i-1][n]-dp1[i-1][j]+dp2[i][j-1];
即可的**
#include
#include
#include
#include
#include
#include
#define maxn 1005
#define pi 10000
using
namespace std;
typedef
long
long ll;
int n,m;
ll dp1[maxn]
[maxn]
;//儲存的是奇數列字首和
ll dp2[maxn]
[maxn]
;//儲存的是偶數列的字首和;
intmain()
if(dp2[i][1
]>pi)
for(
int j=
1;j<=n;j++
) dp2[i]
[j]%
=pi;
}else
if(dp1[i][2
]>pi)
for(
int j=
2;j<=n;j++
) dp1[i]
[j]%
=pi;}}
if(m%2)
cout<[n]%pi
cout<[n]%pi
}
藍橋杯模擬賽 擺動序列 題目 題解
題目 問題描述 如果乙個序列的奇數項都比前一項大,偶數項都比前一項小,則稱為乙個擺動序列。即 a 2i a 2i 小明想知道,長度為 m,每個數都是 1 到 n 之間的正整數的擺動序列一共有多少個。輸入格式 輸入一行包含兩個整數 m,n。輸出格式 輸出乙個整數,表示答案。答案可能很大,請輸出答案除以...
2019 藍橋杯省賽 B 組模擬賽(一)
d.結果填空 馬的管轄 e.填空 lis f.程式設計 找質數 思路 因為時間複雜度的問題,o n n 的時間複雜度可能會超時,可以選擇的篩選素數的方法有埃氏篩法o n logn 尤拉篩法,這裡選的是尤拉篩法o n 直接遍歷找兩個素數相加等於n 因為要求字典樹最小,所以不會超時 ac include...
2018 藍橋杯省賽 B 組模擬賽(一)
給你乙個序列,請你在其中求出一段最長嚴格上公升的部分,它不一定要連續。include includeusing namespace std int f 10000 b 10000 int lis int n res max res,f i return res 1 int main printf d...