问题描述
如果一个序列满足下面的性质,我们就将它称为摆动序列:
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" #include "vector" #include "algorithm" using namespace std; //统计有多少个摆动序列 int count1=0; void checkSeq(vector<int> &seq) { if(seq.size()<=2) { do { for (int i = 0; i < seq.size(); ++i) { cout<<seq[i]<<' '; } cout<<endl; // 统计摆动序列 count1++; } while (next_permutation(seq.begin(),seq.end())); return; } do { for (int i = 2; i < seq.size(); ++i) { // 判断是否满足摆动序列的条件 if((seq[i-1]>seq[i-2] and seq[i]<seq[i-2]) or (seq[i-1]<seq[i-2] and seq[i]>seq[i-2])) { for (int j = 0; j < seq.size(); ++j) { cout<<seq[j]<<' '; } // 统计摆动序列 count1++; cout<<endl; } } } while (next_permutation(seq.begin(),seq.end())); } void printer(vector<int> &seq) { for (int i = 0; i < seq.size(); ++i) { cout<<seq[i]<<'\t'; } cout<<endl; } //对vector进行切片 vector<int> sliceV(vector<int>& seq,int i,int j) { vector<int>subseq; for(;i<=j;i++) { subseq.push_back(seq[i]); } return subseq; } //从vector选取n个数的每种情况都存在path这个里面 void combinations(std::vector<int> &nums, int n, std::vector<int> path) { if (path.size() == n) { // 已经选够了n个数 checkSeq(path); return; } if (nums.empty()) { // 序列已经全部遍历完成 return; } int num = nums[0]; nums.erase(nums.begin()); // 这个数字不选时的情况 combinations(nums, n, path); path.push_back(num); // 这个数字选择时的情况 combinations(nums, n, path); nums.insert(nums.begin(), num); } int main() { // 生成序列 int n; cin>>n; vector<int> seq; seq.reserve(n); for (int i = 1; i <= n; ++i) { seq.push_back(i); } for (int i = 2; i <= seq.size(); ++i) { vector<int> path; combinations(seq,i,path); } cout<<"摆动序列:"<<count1<<endl; return 0; }