AcWing 187. 导弹防御系统(最长上升子序列模型 + 贪心 + dfs求最小步数)

题目链接


题目描述

为了对抗附近恶意国家的威胁,R 国更新了他们的导弹防御系统。
一套防御系统的导弹拦截高度要么一直 严格单调 上升要么一直 严格单调 下降。
例如,一套系统先后拦截了高度为 3 和高度为 4 的两发导弹,那么接下来该系统就只能拦截高度大于 4 的导弹。
给定即将袭来的一系列导弹的高度,请你求出至少需要多少套防御系统,就可以将它们全部击落。

题目思路

结合acwing 1010,爆搜一下每个元素分别放到上升序列和下降序列的情况即可。


题目代码

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 55;

int n;
int q[N];
int up[N], down[N];
int ans;

void dfs(int u, int su, int sd)  //su表示上升序列个数,sd表示下降序列个数
{
    if(su + sd >= ans) return;
    if(u == n)
    {
        ans = su + sd;
        return;
    }
    
    //情况1:将当前数放到上升子序列中
    int k = 0;
    while(k < su && up[k] >= q[u]) k ++;
    int t = up[k];
    up[k] = q[u];
    if(k < su) dfs(u + 1, su, sd);
    else dfs(u + 1, su + 1, sd);
    up[k] = t;
    
    //情况2:将当前数放到下降子序列中
    k = 0;
    while(k < sd && down[k] <= q[u]) k ++;
    t = down[k];
    down[k] = q[u];
    if(k < sd) dfs(u + 1, su, sd);
    else dfs(u + 1, su, sd + 1);
    down[k] = t;
}

int main()
{
    while(cin >> n, n)
    {
        for(int i = 0; i < n; i ++ ) cin >> q[i];
        
        ans = n;  //最多有n个
        dfs(0, 0, 0);
        
        cout << ans << endl;
    }
    
    return 0;
}
posted @   esico  阅读(33)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示