zoukankan      html  css  js  c++  java
  • 最大子序列、最长递增公共子序列、最长递增子序列、最长公共子串、最长公共子序列、字符串编辑距离

    http://www.cnblogs.com/zhangchaoyang/articles/2012070.html

    最大子序列

    最大子序列是要找出由数组成的一维数组中和最大的连续子序列。比如{5,-3,4,2}的最大子序列就是 {5,-3,4,2},它的和是8,达到最大;而 {5,-6,4,2}的最大子序列是{4,2},它的和是6。你已经看出来了,找最大子序列的方法很简单,只要前i项的和还没有小于0那么子序列就一直向后扩展,否则丢弃之前的子序列开始新的子序列,同时我们要记下各个子序列的和,最后找到和最大的子序列。

     http://acm.hdu.edu.cn/showproblem.php?pid=1003

    //模板,思想。
    #include<stdio.h>
    #define Min -999999
    int main()
    {
        int data[100000],start,end,t,i;
        int m;
        scanf("%d",&m);
        for(t=1;t<=m;t++)
        {
            int n;
            scanf("%d",&n);
            for ( i=1; i<=n;i++)
                scanf("%d",&data[i]);
            int max = Min;
            int k=1;
            int sum = 0;
            for (i=1; i<=n; i++)
            {
                sum = sum + data[i];
                //printf("sum=%d
    ",sum);
                if (sum > max)
                {
                  //  printf("max=%d
    ",max);
                    max = sum;
                    start=k;
                    end=i;
                }
                if(sum<0)
                {
                    sum=0;
                    k=i+1;
                }
            }
            printf("Case %d:
    ",t);
            printf("%d %d %d
    ",max,start,end);
            if(t!=m)
                printf("
    ");
         }
        return 0;
    }
    

     最长公共递增序列

    http://acm.hdu.edu.cn/showproblem.php?pid=1423

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int a[600],b[600];
    int GCIS(int l1, int l2)
    {
         int DP[600];
         int i,j,k,max;
        memset(DP,0,sizeof(DP));
        for (i=1; i<=l1; i++)
        {
              k=0;
            for (j=1; j<=l2; j++)
            {
                if (b[j-1]<a[i-1] && DP[j]>DP[k])
                           k=j;
                if (b[j-1]==a[i-1] && DP[k]+1>DP[j])
                    DP[j]=DP[k]+1;
            }
        }
        for(max=0,i=1; i<=l2; i++)
            if (DP[i]>DP[max]) max=i;
            return DP[max];
    }
    int main()
    {
        int T,n,m,i;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
            for(i=0; i<n; i++)
                scanf("%d",&a[i]);
            scanf("%d",&m);
            for(i=0; i<m; i++)
                scanf("%d",&b[i]);
         printf("%d
    ",GCIS(n,m));
           if(T) printf("
    ");
        }
        return 0;
    }

    最长公共递增序列记录路径:zoj

    http://blog.csdn.net/cclsoft/article/details/4537299

    最长公共子序列、子序列问题。

    http://acm.hdu.edu.cn/showproblem.php?pid=1159

    若str1[i]=str2[j]   dp[i][j]=dp[i-1][j-1]+1
    若str1[i]!=str2[j]  dp[i][j]=max(dp[i-1][j],dp[i][j-1])
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    char str1[1005],str2[1005];
    int dp[1005][1005];
    int main()
    {
          int i,j;
       while(~scanf("%s%s",str1,str2))
       {
           memset(dp,0,sizeof(dp));
          int l1=strlen(str1);
          int l2=strlen(str2);
          if(str1[0]==str2[0])
              dp[0][0]=1;
           else
            dp[0][0]=0;
            for(i=1;i<l1;i++)
               {
                if(str1[i]==str2[0])
                       dp[i][0]=1;
                else
                    dp[i][0]=dp[i-1][0];
    
               }
               for(i=1;i<l2;i++)
                {
                    if(str1[0]==str2[i])
                        dp[0][i]=1;
                     else
                        dp[0][i]=dp[0][i-1];
                }
    
          for(i=1;i<l1;i++)
            {
                for(j=1;j<l2;j++)
                  {
                      if(str1[i]==str2[j])
                          dp[i][j]=dp[i-1][j-1]+1;
                       else
                          dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
                    //printf("dp=%d
    ",dp[i][j]);
                  }
            }
           printf("%d
    ",dp[l1-1][l2-1]);
       }
       return 0;
    }

     最长递增子序列:

    http://poj.org/problem?id=2533

    这是我觉得简单一点的模板。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    int a[10000];
    int los(int l)
    {
       int dp[10000];
       int i,j,k,max;
       memset(dp,0,sizeof(dp));
      for(i=1;i<l;i++)
    		for(j=0;j<i;j++)
    			if(a[j]<a[i]&&dp[i]<=dp[j])
    				dp[i]=dp[j]+1;
         for(max=0,i=1; i<=l; i++)
            if (dp[i]>dp[max])
                max=i;
            return dp[max];
    }
    

      但是我自己做的:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    int a[10000];
    int los(int l)
    {
       int dp[10000];
       int i,j,k,max;
       memset(dp,0,sizeof(dp));
       for(i=1;i<=l;i++)
         {
                k=0;
             for(j=1;j<=i;j++)
               {
                    if(i==j)
                      continue;
                  if(a[i-1]>a[j-1])
                        k=j;
                  if(dp[k]+1>dp[i]&&k!=0)
                      dp[i]=dp[k]+1;
               }
         }
         for(max=0,i=1; i<=l; i++)
            if (dp[i]>dp[max])
                max=i;
            return dp[max];
    }
    int main()
    {
        int i,n;
        while(~scanf("%d",&n))
        {
             for(i=0;i<n;i++)
                scanf("%d",&a[i]);
            printf("%d
    ",los(n)+1);
        }
        return 0;
    }

     但是有时最长递增子序列的时间缩短。

    http://poj.org/problem?id=3903

    题意:依旧是一道LIS的裸题
    思路:要注意数据比较多,要用二分的优化法,原本是与POJ2533一样的题,但是用2533的代码只改下数组大小是过不了的,WA了几次,后来发现二分函数需要改进,于是改成了下面的方式,而且这个二分函数用在2533也是可以的
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    int a[100005],c[100005];
    int n;
    int find(int size,int k)
    {
        int l,r,mid;
        l=1;r=size;
        while(l<=r)
        {
             mid=(l+r)/2;
            if(k>c[mid])
               l=mid+1;
             else
              r=mid-1;
        }
        return l;
    }
    int LIS()
    {
        int i;
        int cnt=1;
        c[++cnt]=a[1];
        for(i=2;i<=n;i++)
         {
             if(a[i]>c[cnt])
                 c[++cnt]=a[i];
              else
              {
                  int k=find(cnt,a[i]);
                  c[k]=a[i];
              }
         }
         return cnt-1;
    }
    int main()
    {
      int i;
      while(~scanf("%d",&n))
      {
          for(i=1;i<=n;i++)
            scanf("%d",&a[i]);
         printf("%d
    ",LIS());
      }
    }

    接下来就是这个网站:

    http://www.cnblogs.com/zhangchaoyang/articles/2012070.html

  • 相关阅读:
    请求重定向,请求转发
    post、get方法乱码问题
    Servlet
    修改Servlet模板,让Servlet更清新
    Java-Python对垒之质数计算
    使用Packet Tracer对不同网段组网模拟
    哑编码的两种方法
    AdaBoost scikit-learn相关参数
    KNN scikit-learn相关参数
    递归思想的应用-根据二叉树的中序遍历和前序遍历重建二叉树
  • 原文地址:https://www.cnblogs.com/cancangood/p/3970353.html
Copyright © 2011-2022 走看看