题解 | #拦截导弹#

拦截导弹

https://www.nowcoder.com/practice/218f3db1f66d465bbf9578625aa90785

根据 Dilworth 定理(一个有序集合的最小链划分数等于最大反链的大小),我们可以知道:

  • 最小链划分数:把导弹高度序列划分成若干条递减序列所需的最小数量。
  • 最大反链的大小:一个最长上升子序列的长度(因为两个元素不可比较的意思就是:它们可以构成一个递增的关系)

可以将序列化分为若干个递减子序列 =》 通过找到最长上升子序列的数量来求解

  • 计算最长不增子序列长度(代表最多能拦截的导弹数)。
  • 计算最长上升子序列的数量(代表最少需要的拦截系统数)。
  • #include <algorithm>
    #include <cstring>
    #include <functional>
    #include <iostream>
    #include <vector>
    using namespace std;
    
    const int N = 1010;
    int a[N];
    int f[N];
    
    int maxLength(int n) {
        int res = 0;
        for (int i = 0; i < n; i ++) {
            f[i] = 1;
            for (int j = 0; j < i; j ++) {
                if (a[i] <= a[j]) f[i] = max(f[j] + 1, f[i]);
            }
            res = max(res, f[i]);
        }
        return res;
    }
    
    int minSystem(int n) {
        int res = 0;
        for (int i = 0; i < n; i ++) {
            f[i] = 1;
            for (int j = 0; j < i; j ++) {
                //Dilworth
                if (a[i] > a[j]) {
                    f[i] = max(f[i], f[j] + 1);
                }
            }
            res = max(f[i], res);
        }
        return res;
    }
    
    
    int main() {
        int n;
        cin >> n;
        for (int i = 0; i < n; i ++) cin >> a[i];
    
        cout << maxLength(n) << endl;
        memset(f, 0, sizeof f);
        cout << minSystem(n) << endl;
        return 0;
    }
    

    全部评论

    相关推荐

    qz鹿:*** 祝他毕业就失业
    点赞 评论 收藏
    分享
    评论
    点赞
    收藏
    分享
    牛客网
    牛客企业服务