题意:
现在来了一系列导弹,一套导弹防御系统可以抵挡一个上升子序列的炮弹或者是下降子序列的炮弹,问最少需要多少套导弹防御系统才能抵挡住所有的炮弹。
分析:
对于每个炮弹,有两种大方向,就是放在上升子序列里面或者是放在下降子序列里面,对于放在上升子序列的情况,如果当前已经有的子序列的结尾比这个炮弹小的话就放在比它小的最大的子序列里面,如果没有的话就重新开一个子序列 ,可以证明这些子序列的末尾是严格单调递减的,下降子序列的规律则反之,因为数据量是50,所以咱们可以采用搜索剪枝的方法,下面具体请看代码:
#include<iostream>
#include<cstring>
using namespace std;
const int N = 55;
int a[N],up[N],down[N],n,ans;
void dfs(int u,int su,int sd){
if(su + sd >= ans) return ;
if(u == n){
ans = su + sd;
return;
}
int k = 0;
while(k < su && up[k] >= a[u]) k++;
int t = up[k];
up[k] = a[u];
if(k >= su) dfs(u+1,su+1,sd);
else dfs(u+1,su,sd);
up[k] = t;
k = 0;
while(k < sd && down[k] <= a[u]) k++;
t = down[k];
down[k] = a[u];
if(k >= sd) dfs(u+1,su,sd+1);
else dfs(u+1,su,sd);
down[k] = t;
}
int main(){
while(cin>>n,n){
ans = n;
for(int i=0;i<n;i++) cin>>a[i];
dfs(0,0,0);
cout<<ans<<endl;
}
return 0;
}