zoukankan      html  css  js  c++  java
  • 线性DP模板

    • 最长上升子序列

      • 定义

        • 设有由(n)个不相同的整数组成的数列,记为: (b_1,b_2...b_n)(b_i!=b_j(i!=j))
          若存在(i_1<i_2<...<i_n)且有(b_{i_1}<b_{i_2}...<b_{i_3})则称为长度为(e)的不下降序列。
      • (O(n^2))的做法

      • int lis(int a[], int n) {
            int f[N], ans = 0;
            for(int i = 1; i <= n; i++) f[i] = 1;
            for(int i = 1; i <= n; i++) {
                for(int j = 1; j < i; j++)
                    if (a[j] < a[i] && f[i] < f[j] + 1)
                        f[i] = f[j] + 1;
                ans = max(ans, f[i]);
            }
            return ans;
        }
        
      • (O(n log n))的做法

        • 对于(n^2)的写法,状态是无法优化的,第二维是求(j~i)符合条件的最大子序列和
          (b(i))定义为长度为(i)的最后一位数

        • 看定义可能不太懂,因为我就没看懂
          看着挺复杂,其实也没啥,看代码注释吧

      • int lis(int a[], int n) {
            int f[N], cnt = 1;
            f[cnt] = a[1];
            for(int i = 2; i <= n; i++) {
                if (a[i] > f[cnt]) f[++cnt] = a[i];
                //求上升序列,如果a[i]比最后一位大,就在后面再添一个
                else f[lower_bound(f+1, f+cnt+1, a[i])-f] = a[i];
                //找到比他小的替换掉他
                //upper_bound() 用到库<algorithm>
                //也可以手写二分
            }
            return cnt;
        }
        
    • 最长公共子串

      • 定义

        • 一列字符C既是A的子串,又是B的子串,就称C为A和B的公共子串
          (这里子串指的是连续的)
      • (O(n^2))

      • scanf("%s %s", a+1, b+1);
        n = strlen(a+1); m = strlen(b+1);
        for(int i = 1; i <= n; i++)
            for(int j = m; j > 0; j--) {
                if (a[i] == b[j])
                    s[j] = s[j-1] + 1, ans = max(ans, s[j]);
                else s[j] = 0;
            }
        
    • 最长公共子序列

      • 定义

        • 一列字符C既是A的子序列,又是B的子序列,就称C为A和B的公共子序列
          (这里子序列可以不连续)
      • (O(n^2))

      • for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++)
                if (a[i] == b[j]) f[i][j] = f[i-1][j-1] + 1;
                else f[i][j] = max(f[i-1][j], f[i][j-1]);
        //f[n][n]为最后的结果
        
      • (O(nlogn))

        • 没有重复数字的直接用离散化处理,有重复的用vector记录,放进b数组的时候按从后往前的顺序排列
      • 无重复

      • scanf("%d", &n);
        tot = 0;
        for(int i = 1; i <= n; i++)
            scanf("%d", &a[i]), m[a[i]] = ++tot;
        for(int i = 1; i <= n; i++)
            scanf("%d", &b[i]), b[i] = m[b[i]];
        tot = 0;
        s[++tot] = b[1];
        for(int i = 2; i <= n; i++) {
            if (s[tot] < b[i]) s[++tot] = b[i];
            else s[lower_bound(s+1, s+tot+1, b[i])-s] = b[i];
        }
        printf("%d
        ", tot);
        
      • 有重复

      • scanf("%d", &n);
        for (int i = 1, x; i <= n; i++)
            scanf("%d", &x), m[x].push_back(i);
        for (int i = 1, x; i <= n; i++) {
            scanf("%d", &x);
            for (int j = m[x].size()-1; j >= 0; j--)
                a[++len] = m[x][j];
        }
        f[cnt=1] = a[1];
        for (int i = 2; i <= len; i++)
            if (a[i] > f[cnt]) f[++cnt] = a[i];
            else f[lower_bound(f+1, f+cnt+1, a[i])-f] = a[i];
        printf("%d
        ", cnt);
        
  • 相关阅读:
    急招.NET系列职位
    程序员成长的三个方法
    xwebkitspeech
    张小龙的产品
    浅析商业银行“业务连续性管理体系”的构建
    Sonar for dotNet
    Moles测试Contrustor时候遇到的一个问题
    EntityFramework 用Moles的mock
    Accessor中Generic的元素是internal/private的会导致转换失败的异常
    Android自用Intent 介绍
  • 原文地址:https://www.cnblogs.com/Z8875/p/13178985.html
Copyright © 2011-2022 走看看