蓝桥杯-算法训练-摆动序列

算法训练 摆动序列  
时间限制:1.0s   内存限制:512.0MB
问题描述
  如果一个序列满足下面的性质,我们就将它称为摆动序列:
  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

这道题的思路很直观,从1开始到k去找满足条件的数,

1.满足两两不相等,采用记忆化搜索,用visit[i]=1来记录之前已经遍历过的数;(别忘了在递归结束后将visit[i]置零,因为在搜索下一个数的时候这个数还没有被访问)

2.满足和前两个数比较,函数传参时传递前两个数,当(i>last&&i>last_last)||(i<last&&i<last_last)时继续找下一个数。

3.cnt变量用来存放要求的序列个数。代码如下:


#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
const int maxsize=10000;
int k;
int visit[25]={0};
int cnt=0;//存放要求的序列个数
void dp(int last,int last_last)//传递上一个和上上个数
{
	int i,j;
	if(!last)//初始化条件,让序列的个数等于2
	{
		for(i=1;i<=k;i++)
		{
			visit[i]=1;
			for(j=1;j<=k;j++)
			{
				if(!visit[j])
				{
					visit[j]=1;
					cnt++;
					dp(j,i);
					visit[j]=0;
				}
			}
			visit[i]=0;
		}
	}
	else
	{
		for(i=1;i<=k;i++)
		{
			if(visit[i]||(i>last&&i>last_last)||(i<last&&i<last_last)) continue;//如果不满足条件继续找下一个数
			else
			{
				visit[i]=1; //将该数置为已访问
				cnt++;
				dp(i,last);
				visit[i]=0; //用完清零		
			}
		}	
	}
	return;
	
}
int main()
{
	cin>>k;
	dp(0,0);//传参0,使函数满足初始条件
	cout<<cnt;
	return 0;
}


猜你喜欢

转载自blog.csdn.net/murphypu/article/details/67630555
今日推荐