P1020 [NOIP1999 普及组] DP + Dilworth 定理

题意

传送门 P1020 [NOIP1999 普及组] 导弹拦截

题解

设导弹飞行高度数组为 H H H,则单个系统能拦截的最多导弹,为 H H H 的最长不升子序列。根据 D i l w o r t h Dilworth Dilworth 定理,偏序集中最大反链的大小等于最小链划分的大小。那么拦截所有导弹所需的系统数目等于以 i < j , H [ i ] ≥ H [ j ] i<j,H[i]\geq H[j] i<j,H[i]H[j] 为关系的二维偏序集的最小链划分,即最大反链的大小。在偏序集中,第一维不同值的 i i i 唯一, i > j i>j i>j 时一定不满足关系,则问题转化为求解满足 i < j , H [ i ] < H [ j ] i<j,H[i]<H[j] i<j,H[i]<H[j] 的最大索引集合,即 L I S LIS LIS 问题。二分优化求解 D P DP DP,总时间复杂度 O ( N log ⁡ N ) O(N\log N) O(NlogN)

#include <bits/stdc++.h>
using namespace std;
const int maxn = 100005, inf = 0x3f3f3f3f;
int N, H[maxn], dp[maxn];

int main()
{
    
    
    while (cin >> H[N])
        ++N;
    for (int i = 0; i < N; ++i)
        *upper_bound(dp, dp + N, H[i], greater<int>()) = H[i];
    cout << lower_bound(dp, dp + N, 0, greater<int>()) - dp << '\n';
    memset(dp, 0x3f, sizeof(dp));
    for (int i = 0; i < N; ++i)
        *lower_bound(dp, dp + N, H[i]) = H[i];
    cout << lower_bound(dp, dp + N, inf) - dp << '\n';
    return 0;
}

猜你喜欢

转载自blog.csdn.net/neweryyy/article/details/119479793