问题描述
如果一个序列满足下面的性质,我们就将它称为摆动序列:
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,请求出满足上面要求的序列的个数。
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
#include<iostream>
using namespace std;
int main()
{
int k,sum=0;
cin >> k;
for (int i = 1; i <= k; i++)
{
sum = (sum + i - 1) * 2;
}
cout << sum << endl;
return 0;
}
没错,你没看错,这个题是有规律的!
当然博主没看出来规律是啥 TVT
但是这不妨碍我在
运行超时的时候
总结一下规律 O.O 然后就发现了这个算法23333
这里还是给一下我原来的代码:
#include<iostream>
#include<map>
using namespace std;
int k, A[20];
int sum = 0;
map<int, int>m;
void Xunhuan(int n)
{
for (int i = 1; i <= k; i++)
{
if (!m.count(i))
{
int t = sum;
A[n] = i;
m[i] = 1;
if (n < 2||((A[n - 1] > A[n - 2] && A[n] < A[n - 2]) || (A[n - 1]<A[n - 2] && A[n]>A[n - 2])))
sum++;
if (sum > t&&n < k - 1)
Xunhuan(n + 1);
m.erase(i);
}
}
}
int main()
{
cin >> k;
for (int i = 1; i <= k; i++)
{
A[0] = i;
m[i] = 1;
Xunhuan(1);
m.erase(i); //注意回溯
}
cout << sum << endl;
return 0;
}
这里就是用了一个递归,方法就是先确定一个数列的第一个数,即主函数的循环内容,然后用
Xunhuan()这个调用函数来查找
在前面的数都确定的情况下,有多少符合条件的。