闲谈:搜索是个神奇的东西,我也不知道为什么2^50能过.可能只是因为最坏是2^50左右吧QAQ.
这题思路是很简单的,对于每个点,我们有两个选择.一是放到上升序列中去,二是放到下降序列中去,假如都不能放,那么就要自己重新开一个.然后直接搜索递归即可.基于最优解肯定是要放到最近的序列连续.然后第一次找到了位子就是最优的了.
下面是代码:
#include <bits/stdc++.h>
using namespace std;
const int N=55;
int a[N],n,up[N],down[N];
bool dfs(int dep,int u,int xu,int xd)//最多开dep个序列,现在覆盖到了第几个,我的上升序列有了多少个,我的下降序列有多少个.
{
if(xu+xd>dep) return false;
if(u==n) return true;
bool flag=false;
//枚举上升
for(int i=1;i<=xu;i++)
{
if(a[u]>up[i])
{
int t=up[i];
up[i]=a[u];
flag=true;
if(dfs(dep,u+1,xu,xd)) return true;
up[i]=t;
break;
}
}
//假如不可以连续,创立新的
if(!flag)
{
up[xu+1]=a[u];
if(dfs(dep,u+1,xu+1,xd)) return true;
}
flag=false;
//枚举下降
for(int i=1;i<=xd;i++)
{
if(a[u]<down[i])
{
int t=down[i];
down[i]=a[u];
flag=true;
if(dfs(dep,u+1,xu,xd)) return true;
down[i]=t;
break;
}
}
//假如不可以连续,创立新的
if(!flag)
{
down[xd+1]=a[u];
if(dfs(dep,u+1,xu,xd+1)) return true;
}
//假如都不可以肯定return false呗.
return false;
}
int main()
{
while(cin>>n,n)
{
for(int i=0;i<n;i++) scanf("%d",&a[i]);
int depth=1;
while(!dfs(depth,0,0,0)) depth++;
cout<<depth<<endl;
}
return 0;
}
京公网安备 11010502036488号