問題 1630: [藍橋杯][算法訓練VIP]擺動序列
時間限制: 1Sec 內存限制: 128MB 提交: 8 解決: 3
題目描述
如果一個序列滿足下面的性質,我們就將它稱爲擺動序列:
1. 序列中的所有數都是不大於k的正整數;
2. 序列中至少有兩個數。
3. 序列中的數兩兩不相等;
4. 如果第i – 1個數比第i – 2個數大,則第i個數比第i – 2個數小;如果第i – 1個數比第i – 2個數小,則第i個數比第i – 2個數大。
比如,當k = 3時,有下面幾個這樣的序列:
1 2
1 3
2 1
2 1 3
2 3
2 3 1
3 1
3 2
一共有8種,給定k,請求出滿足上面要求的序列的個數。
輸入
輸入包含了一個整數k。(k< =20)
輸出
輸出一個整數,表示滿足要求的序列個數。
樣例輸入
3
樣例輸出
8
提示
C語言在線學習平臺微信號dotcpp
來源
算法訓練
思路:用dfs搜索的全排列改一下就行,但是有幾個點要注意,不然會超時,看註釋。
代碼:
#include<iostream>
#include<cstdio>
#include<string.h>
#define in(x) scanf("%d",&x)
#define out(x) printf("%lld",x)
using namespace std;
int n,vis[25],k[25];
long long int sum=0;
bool judge(int num,int i)
{
if(i==2||i==1) return true;
if(k[i-1]>k[i-2]&&num<k[i-2]||k[i-1]<k[i-2]&&num>k[i-2]) return true;
else return false;//第二個if每次放入都判斷,這樣沒有後效性
}
void dfs(int index)
{
if(index>n) return;
for(int i=1;i<=n;i++){
if(!vis[i]&&judge(i,index)){//之前寫的是先搜索再判斷結果超時很嚴重
vis[i]=1,k[index]=i; //後來參考別人的先判斷再搜索(神剪枝)
if(index>=2){
sum++;
}
dfs(index+1);
vis[i]=0;
}
}
}
int main()
{
sum=0;
in(n);
dfs(1);
out(sum);
}