题目描述
给定一个序列, 求可以用多少个严格上升或者严格下降的子序列包含完这整个序列
样例
Sample Input
5
3 5 2 4 1
0
Sample Output
2
思路
- 以寻找递增子序列为例, 我们遍历每个元素, 寻找之前的递增子序列中, 有没有大于它的, 有就将它放在全面的那个序列的后面, 没有就再开一个序列, 即是总序列数加一, 递减子序列一样的操作。
- 对于每个数, 我们都去尝试放入递增和递减这两种情况,搜索最后的答案
#include <iostream>
#include <cstring>
#include <sstream>
using namespace std;
const int N = 1010;
string s;
int a[N], Up[N], Down[N];
int n;
int ans;
void dfs(int u, int upNum, int downNum)
{
if(upNum + downNum >= ans) //剪枝
return;
if(u > n)
{
if(upNum + downNum < ans)
ans = upNum + downNum;
return ;
}
int k = 1; // 寻找递增的子序列
while(k <= upNum && a[u] <= Up[k]) k++;
int t = Up[k];
Up[k] = a[u];
if(k > upNum)
dfs(u + 1, upNum + 1, downNum);
else dfs(u + 1, upNum, downNum);
Up[k] = t;
k = 1; //寻找递减的子序列
while(k <= downNum && a[u] >= Down[k]) k++;
t = Down[k];
Down[k] = a[u];
if(k > downNum)
dfs(u + 1, upNum, downNum + 1);
else dfs(u + 1, upNum, downNum);
Down[k] = t;
}
int main()
{
while(cin >> n, n)
{
for(int i = 1; i <= n; i++)
cin >> a[i];
ans = n;
dfs(1, 0, 0);
cout << ans <<endl;
}
return 0;
}