您的位置:首页 > 其它

算法训练 摆动序列

2017-02-24 15:48 183 查看
 算法训练 摆动序列  

时间限制: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

 

刚开始的时候发现是要用状态压缩的动态规划做,但是对这类题目确实是没有思路的。

然后自己就在网上找了一些代码学习,发现这类似深度搜索的感觉,先是对所以情况就是深搜+枚举,for循环判断是否符合条件

代码

#include <cstdio>
#include <iostream>
using namespace std;

const int maxx = 22;
int book[maxx],data[maxx];
int sum,n;

void bfs(int t)
{
if(t>1)
{
if(t == 2)
{
sum++;
}
else
{
int flag = 1;
for(int i = t-1; i >= 2;i--)
{
if((data[i - 1] - data[i - 2])*(data[i]-data[i - 2]) >= 0)
{
flag = 0;
break;
}
}
if(flag == 1)
{
sum++;
}
else
{
return ;
}
}
}

for(int i = 1;i <= n;i++)
{
if(book[i] == 0)
{
data[t] = i;
book[i] = 1;
bfs(t + 1);
book[i] = 0;
}
}
return ;
}

int main()
{
cin >> n;
sum=0;
bfs(0);
cout << sum <<endl;
return 0;
}


又在网上查了一下相关步骤,发现这是一个规律题目。                                                               首先,如果是1的话构不成摆动序列,而对于2来说是任意组成的符合条件的两个数都是构成摆动序列,顺序问题是Cn2*2,对于3来说是从中选取三个数,第一个数确定以后,后面的可大可小两种情况,对于奇数,第一个数一定是中间那个数,第二个数可以大,可以小,使后面的确定下来,对于偶数来说,第一个数和第二个数一定是中间的两个数,这样就确定了整体的排列顺序,即从n个数中选择2到n个数的总和*2即为答案,然后C(N,1)+C(n.2)+。。。+C(n,n)=2的n次方-1。所以代码
                                                                                          
#include <stdio.h>
#include <math.h>

int main()
{
int k;
scanf("%d", &k);
printf("%d", (int)(pow(2, k) - k - 1) * 2);
return 0;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: