【 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;
}
posted @ 2020-11-09 19:14  Hyx'  阅读(129)  评论(0编辑  收藏  举报