问题描述
如果一个序列满足下面的性质,我们就将它称为摆动序列:
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>
#include <vector>
#include <algorithm>
using namespace std;
int kinds = 0;
int n;
void dyna(vector<int> prede,int sign[21]) {
if (prede[prede.size()-1] > prede[prede.size()-2]) {
for (int i=1;i<prede[prede.size()-2];++i) {
if (sign[i]!=1) {
++kinds;
prede.push_back(i);
sign[i] = 1;
// for(vector<int>::iterator it=prede.begin();it!=prede.end();it++)
// cout << *it << "-";
// cout << endl;
dyna(prede,sign);
sign[i] = 0;
prede.pop_back();
}
}
}
else {
for (int i=prede[prede.size()-2]+1;i<=n;++i) {
if (sign[i]!=1) {
++kinds;
prede.push_back(i);
sign[i] = 1;
// for(vector<int>::iterator it=prede.begin();it!=prede.end();it++)
// cout << *it << "+";
// cout << endl;
dyna(prede,sign);
sign[i] = 0;
prede.pop_back();
}
}
}
}
int main()
{
cin >> n;
for(int i=1;i<=n;i++) {
for (int j=1;j<=n;j++) {
if (i!=j) {
++kinds;
vector<int> pre;
pre.push_back(i);
pre.push_back(j);
int sign[21] = {0};
sign[i] = sign[j] = 1;
// for(vector<int>::iterator it=pre.begin();it!=pre.end();it++)
// cout << *it << " ";
// cout << endl;
dyna(pre,sign);
sign[i] = sign[j] = 0;
}
}
}
cout << kinds << endl;
return 0;
}
1万+

被折叠的 条评论
为什么被折叠?



