您的位置:首页 > 其它

蓝桥杯 算法训练 摆动序列 【排列组合 + DFS】

2017-12-26 01:00 274 查看

算法训练 摆动序列

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

题意: 注意第四个条件

分析: 两种思路吧,第一种是直接dfs爆搜,加些剪纸接口,按照题意来搜,很简单,第二种是直接排列组合来算,现在那例如:k = 10,枚举长度,例如枚举到5时,假如就是1,2,3,4,5吧(其实可以是任意数,毕竟这里只是随便挑5个数,主要是看相对大小),可行的方案数只有两个,一个是 3 2 4 1 5,另一个是 3 4 2 5 1,其实可以找到规律的是,无论你找到长度有多长,也只有两个方案,所以这我们们只需挑出组合数即可

DFS参考函数

#include <bits/stdc++.h>
using namespace std;

bool vis[33];
int arr[33];
int res,n;

void dfs(int idx) {
if(idx == 2) {
res++;
}
if(idx > 2) {
if((arr[idx-2] > arr[idx-3] && arr[idx-1] < arr[idx-3]) ||
(arr[idx-2] < arr[idx-3] && arr[idx-1] > arr[idx-3])){
res++;
} else return ;
}
for(int i = 1;i <= n;i++) {
if(!vis[i]) {
vis[i] = true;
arr[idx] = i;
dfs(idx+1);
vis[i] = false;
}
}
}

int main() {
cin>>n;
dfs(0);
cout<<res<<endl;
return 0;
}


组合参考函数

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

ll fac(ll x) {
if(x == 0) return 1;
ll res = x;
while (--x) res *= x;
return res;
}

ll C(ll n,ll i) {
ll res = fac(n)/fac(i)/fac(n-i);
return res;
}

int main() {
ll n;cin>>n;
ll res = 0;
for(ll i = 2;i <= n;i++) {
res += C(n,i);
}
cout<<res*2<<endl;
return 0;
}


如有错误或遗漏,请私聊下UP,thx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: