acwing 187 导弹防御系统 (最长上升子序列)

题面

在这里插入图片描述

题解

  1. 拦截导弹的升级版,拦截导弹只让使用不上升子序列,我们就只需要考虑两种情况
    在这里插入图片描述
  1. 这道题我们可以使用上升和下降两种序列,那么对于一个数,我们就有4中情况,那么我们就只能dfs暴搜,看这个数放在哪种情况下最优,记得还原状态

代码

#include<bits/stdc++.h>

using namespace std;
const int N = 55;

int n;
int h[N];
int up[N];  //不下降序列 (序列种元素的值是递减的)
int down[N];  //不上升序列 (序列中元素的值是递增的)
int res;

void dfs(int u, int su, int sd) {
    
    
    //剪枝(已经大于最优解)
    if (su + sd >= res) return;

    if (u == n + 1) {
    
      //已经全部放入序列中
        res = su + sd;
        return;
    }
    //1.将当前数放入上升子序列中
    int k = 0;
    while (k < su && up[k] >= h[u]) k++;
    int t = up[k];
    up[k] = h[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] <= h[u]) k++;
    t = down[k];
    down[k] = h[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 = 1; i <= n; i++) cin >> h[i];
        res = n;  //多组输入,记得更新答案
        dfs(1, 0, 0);
        cout << res << endl;
    }


    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_44791484/article/details/115202746