擺動序列

問題 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);
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章