问题描述
如果一个序列满足下面的性质,我们就将它称为摆动序列:
1. 序列中的所有数都是不大于 k k k的正整数;
2. 序列中至少有两个数。
3. 序列中的数两两不相等;
4. 如果第 i – 1 i – 1 i–1个数比第 i – 2 i – 2 i–2个数大,则第 i i i个数比第 i – 2 i – 2 i–2个数小;如果第 i – 1 i – 1 i–1个数比第 i – 2 i – 2 i–2个数小,则第 i i i个数比第 i – 2 i – 2 i–2个数大。
比如,当 k = 3 k = 3 k=3时,有下面几个这样的序列:
1 2
1 3
2 1
2 1 3
2 3
2 3 1
3 1
3 2
一共有8种,给定 k k k,请求出满足上面要求的序列的个数。
输入格式
输入包含了一个整数 k k k。( k < = 20 k<=20 k<=20)
输出格式
输出一个整数,表示满足要求的序列个数。
样例输入
3
样例输出
8
个人思路:虽然题目标记为 D P DP DP,但明显用 D F S DFS DFS更为方便(抽象 d f s dfs dfs)
#include <iostream>
using namespace std;
int k,ans;
int a[100];
bool vis[100]; //标记是否访问
//判断当前点是否满足要求
bool judge(int num, int x) {
if (x == 1 || x == 2)
return true;
if ((a[x - 1] - a[x - 2]) * (num - a[x - 2]) < 0)
return true;
return false;
}
void dfs(int x) {
//大于要求长度则返回
if (x > k)
return;
for (int i = 1; i <= k; ++i) {
if (!vis[i] && judge(i, x)) {
vis[i] = true;
a[x] = i;
//序列必须大于2,才计数
if (x >= 2)
ans++;
dfs(x + 1);
vis[i] = false; //回溯
}
}
}
int main() {
cin >>k;
dfs(1);
cout << ans << endl;
return 0;
}