• Luogu P1020 导弹拦截


    传送门

    这道题信息量好大啊

    1.Dilworth定理

    •   Dilworth定理:对于一个偏序集,最少链划分等于最长反链长度。
    •   Dilworth定理的对偶定理:对于一个偏序集,其最少反链划分数等于其最长链的长度。

      其实就是说,对于一个序列,

      最大上升子序列长度 = 不上升子序列个数,最大不上升子序列长度 = 上升子序列个数,

      最大下降子序列长度 = 不下降子序列个数,最大不下降子序列长度 = 下降子序列个数。

      所以这道题:Q1求最大不上升子序列长度,Q2求不上升子序列个数 = 最大上升子序列长度。

    2.STL函数:lower_bound( )和upper_bound( )

    lower_bound(num,num+L,A)-num; //返回第一个 >=A 的值
    upper_bound(num,num+L,A)-num; //返回第一个 >A 的值
    lower_bound(num,num+L,A,greater<int>())-num; //返回第一个 <=A 的值 
    upper_bound(num,num+L,A,greater<int>())-num; //返回第一个 <A 的值

      只能在单调序列里调用,从前往后找

      lower是>=,upper是>,用greater或者cmp改成<= / <

      得到的是元素的地址,最后减去数组的地址就得到了元素下标。

      其实就是代替了二分查找...二分的写法见P1439 【模板】最长公共子序列

      需要调用<algorithm>库,如果用greater还要调用<iostream>

    注意:

    1.读入时

    while(scanf("%d",&a[++n])!=EOF) {
            continue;
        }
        n--;

    因为是先进行++n操作再判断的,所以多了一次,最后要n--.

    2.Q1每次要求更小的,所以up1[0]要赋值为INF,不能为0.

    代码如下

    动态规划( O(n^2),100分 )

    #include<cstdio>
    #include<iostream>
    using namespace std;
    const int maxn = 200005;
    int n,ans,a[maxn],f[maxn],g[maxn];
    int main() {
        while(scanf("%d",&a[++n])!=EOF) {
            f[n] = 1;
            g[n] = 1;
        }
        for(int i = n; i >= 1; i--)
            for(int j = i+1; j <= n; j++)
                if(a[i] >= a[j])
                    f[i] = max(f[i],f[j]+1);
        for(int i = 1; i <= n; i++)
            ans = max(ans,f[i]);
        printf("%d
    ",ans);
        ans = 0;
        for(int i = n; i >= 1; i--)
            for(int j = i+1; j <= n; j++)
                if(a[i] < a[j])
                    g[i] = max(g[i],g[j]+1);
        for(int i = 1; i <= n; i++)
            ans = max(ans,g[i]);
        printf("%d
    ",ans);
        return 0;
    }
    View Code

    正解( O(nlogn),200分 )

    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    const int maxn = 200005;
    int n,ans,a[maxn],up1[maxn],up2[maxn];
    int main() {
        while(scanf("%d",&a[++n])!=EOF) {
            continue;
        }
        n--;
        up1[0] = maxn;
    for(int i = 1; i <= n; i++) {
            if(a[i] <= up1[ans])
                up1[++ans] = a[i];
            else {
                int k = upper_bound(up1+1,up1+ans+1,a[i],greater<int>())-up1;
                up1[k] = a[i];
            }
        }
        printf("%d
    ",ans);
        ans = 0;
        up2[1] = a[1];
        for(int i = 1; i <= n; i++) {
            if(a[i] > up2[ans])
                up2[++ans] = a[i];
            else {
                int k = lower_bound(up2+1,up2+ans+1,a[i])-up2;
                up2[k] = a[i];
            }
        }
        printf("%d
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    day 66 crm(3) 自创组件stark界面展示数据
    day 65 crm(2) admin源码解析,以及简单的仿造admin组件
    用 Python+nginx+django 打造在线家庭影院
    django -admin 源码解析
    day 64 crm项目(1) admin组件的初识别以及应用
    云链接 接口不允许 情况 解决方法 mysql Host is not allowed to connect to this MySQL server解决方法
    day 56 linux的安装python3 ,虚拟环境,mysql ,redis
    day55 linux 基础以及系统优化
    Codeforces 989 P循环节01构造 ABCD连通块构造 思维对云遮月参考系坐标轴转换
    Codeforces 990 调和级数路灯贪心暴力 DFS生成树两子树差调水 GCD树连通块暴力
  • 原文地址:https://www.cnblogs.com/mogeko/p/10290600.html
Copyright © 2020-2023  润新知