Dilworth 定理

引入

​ 最开始是在复习基础dp的时候,发现的这个定理。 题目在这里最少拦截系统

解法

​ 解决这道问题本身很简单了。一个是贪心,复杂度可以达到O(n * log(n)),代码附在了最后面。核心就是一个小数应该匹配前面比它最近(贪心),且大的数(满足题意)。找到后换该数为这个小数,之后二分查找给定值。

​ 第二个思路是用线段树,查找一个小数应该匹配前面比它最近(贪心),且大的数(满足题意)

思考

​ 转念一想,这题的代码实现岂不是就在求… LIS,最长上升序列?

​ 网上一查还真是,有个Dilworth定理就可以用来证明两个问题等价。

Dilworth定理的阐述

Dilworth定理的证明

​ 该作者证明的很好,我就不瞎掺和了。Dilworth对偶定理的证明 plus,有空可以补一下作者提到的题。

CODE

最后附上贪心题解的代码

const int N = 1e6;
int n;
int a[N];
int up[N];
int main() {
    while (scanf("%d", &n) == 1) {
        int ans = 0;
        for (int i = 0; i < n; ++i) {
            scanf("%d", a+i);
            if (i == 0) {
                up[0] = a[0];
                ans++;
            } else {
                // upper_bound: return ... that > given value
                // lower bound return [first, last )range the first element that >= given value
                int pos = lower_bound(up, up+ans, a[i])-up; 
                if (pos == ans) ans++;
                up[pos] = a[i];
            }
        }
        printf("%d\n", ans);
    }
	return 0;
}