• 线性DP基础--acwing---动态规划


    注意点:1、其实就是讲所有走每一步的时候求大致值就好,然后这个值又会对下面进行影响,就像自己思考问题一样

        2、然后就是需要注意一下边界问题,因为我们这边求最大值,所以需要对边界进行初始化

    #include <iostream>
    #include <cstring>
    #include <string>
    #include <cmath>
    #include <cstdio>
    #include <stdio.h>
    #include <cstdlib>
    #include <algorithm>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #define pub(n) push_back(n)
    #define pob(n) pop_back(n)
    #define sf(n) scanf("%d",&n)
    #define pf(n) printf("%d
    ",n)
    #define slf(n) scanf("lld",&n)
    #define plf(n) printf("lld
    ",&n)
    #define rep(i,a,b) for(int i = a; i <= b ; i ++ )
    #define pre(i,a,b) for(int i = a ; i >= b ; i --)
    #define ll long long
    #define PII pair<int,int>
    #define inf 0x3f3f3f3f3f3f3fll
    #define ull unsigned long long
    #define ios ios::sync_with_stdio(false),cin.tie(0)
    using namespace std;
    const int N = 510,mod=1e9+7;
    
    int n;
    int a[N][N];
    int f[N][N];
    int main()
    {
        ios;
        sf(n);
        rep(i,1,n)
        {
            rep(j,1,i)
            {
                sf(a[i][j]);
            }
        }
        rep(i,0,n)
        {
            rep(j,0,i+1)
            {
                f[i][j]=-inf;
            }
        }
        f[1][1]=a[1][1];
    
        rep(i,2,n)
        {
            rep(j,1,i)
            {
                f[i][j]=max(f[i-1][j-1]+a[i][j],f[i-1][j]+a[i][j]); // select down or right
            }
        }
        int cnt=-inf;
        rep(i,1,n)
        {
            cnt=max(cnt,f[n][i]);
        }
        pf(cnt);
        return 0;
    }
    

    最长上升子序列理解:1、有一说一,样板题,很快就容易,就是当前这个值可以由前面哪里转过来然后max最大长度就行,++就好

    #include <iostream>
    #include <cstring>
    #include <string>
    #include <cmath>
    #include <cstdio>
    #include <stdio.h>
    #include <cstdlib>
    #include <algorithm>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #define pub(n) push_back(n)
    #define pob(n) pop_back(n)
    #define sf(n) scanf("%d",&n)
    #define pf(n) printf("%d
    ",n)
    #define slf(n) scanf("lld",&n)
    #define plf(n) printf("lld
    ",&n)
    #define rep(i,a,b) for(int i = a; i <= b ; i ++ )
    #define pre(i,a,b) for(int i = a ; i >= b ; i --)
    #define ll long long
    #define PII pair<int,int>
    #define inf 0x3f3f3f3f3f3f3fll
    #define ull unsigned long long
    #define ios ios::sync_with_stdio(false),cin.tie(0)
    using namespace std;
    const int N = 1110,mod=1e9+7;
    
    int n;
    int a[N];
    int f[N];
    
    int main()
    {
        ios;
        sf(n);
        rep(i,1,n) sf(a[i]);
    
        rep(i,1,n)
        {
            f[i]=1;
            rep(j,1,i-1)
            {
                if(a[i]>a[j])
                {
                    f[i]=max(f[i],f[j]+1);
                }
            }
        }
        int cnt=-1;// the end index of the max f[i]
        rep(i,1,n)
        {
            cnt=max(cnt,f[i]);
        }
        pf(cnt);
        return 0;
    }
    

      

    最长上升子序列二思考:1、数据量增大的下我们是无法两重循环的,所以得优化,

                2、不难发现没有优化的时候我们是需要枚举出我们是从哪里转过来,然后继续求max

                   3、如果我们要是能够知道_i_前面的数字的最小值的话,岂不是直接查找当前这个值就好了,不需再进行枚举了

                 4、所以,这里f[]数组的含义发生了改变,存的是前面i个数最长上升子序列结尾的最小值

    #include <iostream>
    #include <cstring>
    #include <string>
    #include <cmath>
    #include <cstdio>
    #include <stdio.h>
    #include <cstdlib>
    #include <algorithm>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #define pub(n) push_back(n)
    #define pob(n) pop_back(n)
    #define sf(n) scanf("%d",&n)
    #define pf(n) printf("%d
    ",n)
    #define slf(n) scanf("lld",&n)
    #define plf(n) printf("lld
    ",&n)
    #define rep(i,a,b) for(int i = a; i <= b ; i ++ )
    #define pre(i,a,b) for(int i = a ; i >= b ; i --)
    #define ll long long
    #define PII pair<int,int>
    #define inf 0x3f3f3f3f3f3f3fll
    #define ull unsigned long long
    #define ios ios::sync_with_stdio(false),cin.tie(0)
    using namespace std;
    const int N = 2e6+10,mod=1e9+7;
    
    int n;
    int a[N];
    int f[N];
    
    int main()
    {
        ios;
        sf(n);
        rep(i,0,n-1) sf(a[i]);
    
        int len=0;  //当前最大的长度
        f[0]=-2e9; // after we need to get the min length of adding a[]
    
        rep(i,0,n-1)
        {
            int l=0,r=len;
            while(l<r)
            {
                int mid =(l+r+1) >> 1;
                if(a[i]>f[mid]) l=mid;
                else r=mid-1;
            }
            len=max(len,r+1);
            f[r+1]=a[i];
        }
        pf(len);
    
        return 0;
    }
    

      

    之后就是还有一个最长公共子序列,感觉trie算法更好一点,就不写了

  • 相关阅读:
    常用模块Part(1)
    递归函数
    python 生成器函数
    python 迭代器与生成器
    python 函数进阶
    python 装饰器进阶
    python time模块
    python 初始函数
    python 文件操作
    python 一些小知识
  • 原文地址:https://www.cnblogs.com/jxust-Biao/p/13352679.html
Copyright © 2020-2023  润新知