• 最大连续子序列和,最大上升子序列和,最长上升子序列,最长公共子串,最长公共子序列,最长上升公共子序列


    首先,什么是子串,什么是子序列?

    子串必须连续,子序列可以不连续。    连续子序列就是子串

    最大和最长也不一样,最大是求子序列加起来的数值最大,最长是这个子序列的长度最长。

    最大连续子序列和 或者 最大连续子序列

    其实可以叫做最大子串和

    求一个数列的最大的连续子序列的和是多少,通常还要得到是从哪开始到哪结束。

    例如,hdu1003 http://acm.hdu.edu.cn/showproblem.php?pid=1003

    #include<stdio.h>
    #include<string.h>
    #include<string>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define N 1234567
    #define M 12
    
    int n,a[N];
    
    int main()
    {
        int T;cin>>T;int tt=1;
        while(T--)
        {
            cin>>n;
            for(int i=0;i<n;i++)
                scanf("%d",&a[i]);
            int sum=0,ma,temp=0,st=0,ed=0;
            ma=a[0];
            for(int i=0;i<n;i++)
            {
                if(sum<0)
                {
                    sum=a[i];
                    temp=i;
                }
                else
                {
                    sum+=a[i];
                }
                if(sum>ma)
                {
                    st=temp;
                    ma=sum;
                    ed=i;
                }
            }
            printf("Case %d:
    ",tt++);
            printf("%d %d %d
    ",ma,st+1,ed+1);
            if(T)printf("
    ");
        }
        return 0;
    }

    最大上升子序列和

    求一个数组的上升的子序列和最大是多少

    hdu1087http://acm.hdu.edu.cn/showproblem.php?pid=1087

    #include<stdio.h>
    #include<iostream>
    
    using namespace std;
    #define N 112345678
    #define M 11234
    #define INF 0x3f3f3f3f
    
    int a[N],d[N],n,m;
    
    int main()
    {
        while(cin>>n&&n)
        {
            for(int i=0;i<n;i++)
            {
                scanf("%d",&a[i]);
                d[i]=a[i];
            }
            int ma=d[0];
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<i;j++)
                    if(a[i]>a[j] && d[j]+a[i]>d[i])
                    {
                        d[i]=d[j]+a[i];
                        ma=max(ma,d[i]);
                    }
            }
            cout<<ma<<endl;
        }
        return 0;
    }

    最长上升子序列(LIS)

     入门题poj2553http://poj.org/problem?id=2533 只要求出最长数

    #include<stdio.h>
    #include<iostream>
    using namespace std;
    #define N 112345678
    
    int a[N],d[N],n;
    
    int main()
    {
        while(cin>>n)
        {
            for(int i = 0;i < n; i++)
            {
                scanf("%d",&a[i]);
                d[i]=1;
            }
            int ma=1;
            for(int i = 0; i < n; i++)
            {
                for(int j = 0; j < i; j++)
                {
                    if(a[i] > a[j]  &&  d[j] >= d[i])
                        d[i]=d[j]+1;
                }
                ma=max(ma,d[i]);
            }
            cout<<ma<<endl;
        }
        return 0;
    }

    最长公共子串

    没找到题目,自己写了一下

    #include<string.h>
    #include<iostream>
    #include<stdio.h>
    using namespace std;
    #define N 112345678
    #define M 11234
    #define INF 0x3f3f3f3f
    
    int n,m,a[N],b[N];
    string s,t,p;
    
    int main()
    {
        while(cin>>s>>t)
        {   int ma=0;
            memset(a,0,sizeof(a));
            for(int i=0;i<s.length();i++)
            {
                for(int j=0;j<t.length();j++)
                {
                    if(s[i]==t[j])
                    {
                        if(j==0)
                            a[j]=1;
                        else
                            a[j]=b[j-1]+1;
                    }
                    else
                        a[j]=0;
    //                printf("%d ",a[j]);
    //                if(j==t.length()-1)printf("
    ");
                    if(a[j]>ma)
                    {
                        ma=a[j];
                        p=t.substr(j-ma+1,ma);
                    }
                }
                for(int j=0;j<t.length();j++)
                    b[j]=a[j];
            }
            cout<<"最长公共子串长度: "<<ma<<endl;
            cout<<"公共子串: "<<p<<endl;
        }
        return 0;
    }

     最长公共子序列(LCS)

    poj1458 http://poj.org/problem?id=1458 这是最简单的,只要输出LCS的长度,不需要输出是什么

    #include<string.h>
    #include<string>
    #include<stdio.h>
    #include<iostream>
    
    using namespace std;
    #define M 11234
    #define INF 0x3f3f3f3f
    
    int d[M][M],n,m;
    string s1,s2;
    
    int main()
    {
        while(cin>>s1>>s2)
        {
            for(int i=1;i<=s1.length();i++)
                for(int j=1;j<=s2.length();j++)
            {
    
                if(s1[i-1]==s2[j-1])
                    d[i][j]=d[i-1][j-1]+1;
                else
                    d[i][j] = max(d[i-1][j],d[i][j-1]);
            }
            cout<<d[s1.length()][s2.length()]<<endl;
        }
        return 0;
    }

      如果poj1458 加上输出公共子序列(有多个输出任意一个即可),则代码如下

    #include<string.h>
    #include<string>
    #include<stdio.h>
    #include<iostream>
    
    using namespace std;
    #define M 11234
    #define INF 0x3f3f3f3f
    
    int d[M][M],path[M],n,m;
    string s1,s2;
    
    int main()
    {
        while(cin>>s1>>s2)
        {
            for(int i=1;i<=s1.length();i++)
                for(int j=1;j<=s2.length();j++)
            {
                if(s1[i-1]==s2[j-1])
                    d[i][j]=d[i-1][j-1]+1;
                else
                    d[i][j] = max(d[i-1][j],d[i][j-1]);
            }
            cout<<d[s1.length()][s2.length()]<<endl;
            int i=s1.length(),j=s2.length(),k=0;
            while(d[i][j])
            {
                if(s1[i-1]==s2[j-1])
                {
                    path[k++]=i-1;
                    i--;j--;
                }
                else if(d[i][j]==d[i-1][j])
                    i--;
                else
                    j--;
            }
            printf("路径:");
            for(int i=k-1;i>=0;i--)
                printf("%c", (char)s1[ path[i] ]);
            printf("
    ");
        }
    
        return 0;
    }

    如果要输出所有的最长公共子序列

    (待研究)

      

    hdu1503

    最长上升公共子序列 

    zoj 2432

    #include<algorithm>
    #include<string>
    #include<string.h>
    #include<stdio.h>
    #include<iostream>
    using namespace std;
    #define N 505
    
    int a[N],l1,l2,b[N],ma,f[N][N];
    int pre_i[N][N], pre_j[N][N], path[N], mj;
    
    void solve3()
    {
        memset(f, 0, sizeof(f) );
        memset(pre_i, 0, sizeof(pre_i) );
        memset(pre_j, 0, sizeof(pre_j) );
        for(int i = 1; i <= l1; i++)
        {
            int ma1 = 0, i1 = 0, j1 = 0;
            for(int j = 1; j <= l2; j++)
            {
                f[i][j] = f[i-1][j];
                pre_i[i][j] = i-1;
                pre_j[i][j] = j;
                if(a[i-1] > b[j-1]  &&  f[i-1][j] > ma1)
                {
                    ma1 = f[i-1][j];
                    i1 = i-1;
                    j1 = j;
                }
                if(a[i-1] == b[j-1])
                {
                    f[i][j] = ma1 + 1;
                    pre_i[i][j] = i1;
                    pre_j[i][j] = j1;
                }
    
            }
        }
        ma = mj = -1;
        for(int j = 1; j <= l2; j++)
            if(f[l1][j] > ma)
            {
                ma = f[l1][j];
                mj = j;
            }
        int i = l1, j = mj ,k = 0;
        while( f[i][j] )
        {
            int x = pre_i[i][j], y = pre_j[i][j];
            if(f[i][j] != f[x][y])
            {
                path[k++] = b[j-1];
            }
            i = x;
            j = y;
        }
        cout<<ma<<endl;
        for(i = k-1; i >= 0; i--)
        {
            printf("%d", path[i]);
            if(i > 0) printf(" ");
            else printf("
    ");
        }
    
    }
    
    int main()
    {
        int T;cin>>T;
        while(T--)
        {
            scanf("%d", &l1);
            for(int i = 0; i < l1; i++)
                scanf("%d", &a[i]);
            scanf("%d", &l2);
            for(int i = 0; i < l2; i++)
                scanf("%d", &b[i]);
    
            solve3();
    
        }
    
        return 0;
    }
    /*
    99
    
    5
    1 4 2 5 -12
    4
    -12 1 2 4
    
    9
    3 5 1 6 7 9 1 5 13
    6
    4 6 13 9 13 5
    */
  • 相关阅读:
    【Win 10 应用开发】Toast通知激活应用——前台&后台
    MySQL深入理解
    mysql 索引中的USING BTREE 的意义
    关于PHP将对象数据写入日志的问题
    Golang学习笔记
    git flow 使用步骤
    git flow常用命令
    Nginx Log日志统计分析常用命令
    Nginx配置中的log_format用法梳理(设置详细的日志格式)
    回调函数的原理及PHP实例
  • 原文地址:https://www.cnblogs.com/wmxl/p/4798295.html
Copyright © 2020-2023  润新知