【 LIS 和 LCS 覆盖序列 】 导弹防御系统
传送门
题意
给定\(n\)个导弹的高度,一个导弹防御系统能够防御的导弹要么单调上升要么单调下降
问最少需要多少个导弹防御系统能够防御所有导弹
数据范围
\(1\leq n\leq 50\)
题解
暴力搜索所有可能的方案,对于上升子序列覆盖,求对偶问题:最长不上升子序列
对于下降子序列覆盖,求对偶问题:最长不下降子序列
Code
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<=n;i++)
const int N=1e5+10;
int up[N],down[N];
int a[N];
int n;
int ans=1e10;
void dfs(int u,int inc,int dec){
if(inc+dec>=ans) return;
if(u==n+1){
ans=min(ans,inc+dec);
return;
}
// 求最长不下降子序列,即最长下降子序列对偶问题
int k=1;
while(k<=inc && up[k]<=a[u]) ++k;
int t=up[k];
up[k]=a[u];
if(k<=inc) dfs(u+1,inc,dec);
else dfs(u+1,inc+1,dec);
up[k]=t;
// 求最长不上升子序列,即最长上升子序列的对偶问题
k=1;
while(k<=dec && down[k]>=a[u]) ++k;
t=down[k];
down[k]=a[u];
if(k<=dec) dfs(u+1,inc,dec);
else dfs(u+1,inc,dec+1);
down[k]=t;
}
int main(){
while(scanf("%d",&n),n){
rep(i,1,n) scanf("%d",&a[i]);
ans=1e10;
dfs(1,0,0);
cout<<ans<<endl;
}
return 0;
}