问题描述
如果一个序列满足下面的性质,我们就将它称为摆动序列:
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()这个调用函数来查找 在前面的数都确定的情况下,有多少符合条件的。