zoukankan      html  css  js  c++  java
  • 最长公共子序列、上升子序列、最长上升子序列、最长公共子串

    最长公共子序列

    其实有很多方法可以过,因为在弄DP所以就只写了动态规划的方法:

    动态规划方法

    1、序列str1和序列str2

        ·长度分别为m和n;

        ·创建1个二维数组L[m.n];

        ·初始化L数组内容为0

        ·m和n分别从0开始,m++,n++循环:

        - 如果str1[m] == str2[n],则L[m,n] = L[m - 1, n -1] + 1;

        - 如果str1[m] != str2[n],则L[m,n] = max{L[m,n - 1],L[m - 1, n]}

        ·最后从L[m,n]中的数字一定是最大的,且这个数字就是最长公共子序列的长度

        ·从数组L中找出一个最长的公共子序列

    2、从数组L中查找一个最长的公共子序列

        i和j分别从m,n开始,递减循环直到i = 0,j = 0。其中,m和n分别为两个串的长度。

        ·如果str1[i] == str2[j],则将str[i]字符插入到子序列内,i--,j--;

        ·如果str1[i] != str[j],则比较L[i,j-1]与L[i-1,j],L[i,j-1]大,则j--,否则i--;(如果相等,则任选一个)

    根据上图,我们可以得到其中公共子序列:B C B A 和 B D A B。

     1 # include <map>
     2 # include <queue>
     3 # include <stack>
     4 # include <math.h>
     5 # include <stdio.h>
     6 # include <string.h>
     7 # include <iostream>
     8 # include <algorithm>
     9 # define N 510
    10 using namespace std;
    11 
    12 char s1[N], s2[N];
    13 int dp[N][N];
    14 
    15 int max(int x, int y)
    16 {
    17     if(x > y)
    18         return x;
    19     else
    20         return y;
    21 }
    22 
    23 int main(void)
    24 {
    25     while(gets(s1))
    26     {
    27         gets(s2);
    28         int len1 = strlen(s1);
    29         int len2 = strlen(s2);
    30         for(int i = 0; i <= len1; i++)
    31             for(int j = 0; j <= len2; j++)
    32                 dp[i][j] = 0;
    33         for(int i = 1; i <= len1; i++)
    34         {
    35             for(int j = 1; j <= len2; j++)
    36             {
    37                 if(s1[i-1] == s2[j-1])
    38                     dp[i][j] = dp[i-1][j-1]+1;
    39                 else
    40                 {
    41                     dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
    42                 }
    43             }
    44         }
    45         printf("%d
    ", dp[len1][len2]);
    46     }
    47 
    48     return 0;
    49 }
    View Code


    很好的一篇介绍LCS的文章http://blog.csdn.net/v_july_v/article/details/6695482

    最长上升子序列 

     1 # include <map>
     2 # include <queue>
     3 # include <stack>
     4 # include <math.h>
     5 # include <stdio.h>
     6 # include <string.h>
     7 # include <iostream>
     8 # include <algorithm>
     9 # define N 1010
    10 using namespace std;
    11 
    12 int a[N], dp[N];
    13 
    14 int main(void)
    15 {
    16     int n, m, i, j;
    17     scanf("%d", &n);
    18     for(i = 1; i <= n; i++)
    19         scanf("%d", &a[i]);
    20     dp[1] = 1;
    21     for(i = 2; i <= n; i++)
    22     {
    23         m = 0;
    24         for(j = 1; j < i; j++)
    25         {
    26             if(a[i] > a[j] && m < dp[j])
    27                 m = dp[j];
    28         }
    29         dp[i] = m+1;
    30     }
    31     int nMax = -1;
    32     for(i = 1; i <= n; i++)
    33     {
    34         if(nMax < dp[i])
    35             nMax = dp[i];
    36     }
    37     printf("%d
    ", nMax);
    38 
    39     return 0;
    40 }
    View Code

    上升子序列(最长上升子序列改版  求和)

     1 # include <map>
     2 # include <queue>
     3 # include <stack>
     4 # include <math.h>
     5 # include <stdio.h>
     6 # include <string.h>
     7 # include <iostream>
     8 # include <algorithm>
     9 # define N 1010
    10 using namespace std;
    11 
    12 int a[10000], dp[10000];
    13 int main(void)
    14 {
    15     int n, max, i, j;
    16     while (~scanf("%d",&n))
    17     {
    18         for (i = 0; i < n; i++)
    19             scanf("%d", &a[i]);
    20         dp[0] = a[0];
    21         for (i = 0; i < n; i++)
    22         {
    23             max = 0;
    24             for (j = 0; j < i; j++)
    25             {
    26                 if (a[i] > a[j])
    27                 {
    28                     if (max < dp[j])
    29                         max = dp[j];
    30                 }
    31             }
    32             dp[i] = a[i] + max;
    33         }
    34         int t = 0;
    35         for (i = 0; i < n; i++)
    36         {
    37             if (t < dp[i])
    38                 t = dp[i];
    39         }
    40         printf("%d
    ", t);
    41     }
    42 
    43     return 0;
    44 }
    View Code

    最长公共子串

     1 # include <stdio.h>
     2 # include <string.h>
     3 
     4 int dp[30010], n, t;
     5 char c[101], len[101], a[101][101];     /* 这里存储着状态数列, 长度 */
     6 
     7 int get(int i, int k)                    /* 得到状态 */
     8 {
     9     if (i > n)
    10         return 0;
    11     return get(i+1, k*len[i]) + k * c[i];
    12 }
    13 
    14 int LCS()
    15 {
    16     int p, i, j;
    17     p = get(0, 1);
    18     if (!dp[p])
    19     {
    20         for(i = 1; i <= n-1; i++)
    21             if (a[i][c[i]] != a[i+1][c[i+1]])
    22                 break;
    23         if (i > n - 1)
    24         {
    25             for(i=1; i<=n; ++i)
    26             {
    27                 if (c[i])
    28                     c[i]--;
    29                 else
    30                     break;
    31             }
    32             if (i > n)
    33             {
    34                 j = LCS() + 1;
    35                 if (j >= dp[p])
    36                     dp[p] = j + 1;
    37             }
    38             else
    39             {
    40                 dp[p] = 2;
    41             }
    42             while((--i)>0)
    43             {
    44                 c[i]++;
    45             }
    46         }
    47         else
    48         {
    49             for(i = 1; i <= n; i++)
    50             {
    51                 if(c[i])
    52                 {
    53                     c[i]--;                /* 遍历前一个状态 */
    54                     j = LCS();
    55                     if (j >= dp[p])
    56                         dp[p] = j + 1;
    57                     c[i]++;
    58                 }
    59             }
    60             if (!dp[p])
    61                 dp[p] = 1;
    62         }
    63     }
    64     return dp[p] - 1;
    65 }
    66 
    67 int main(void)
    68 {
    69     int i;
    70     scanf("%d", &t);
    71     while(t--)
    72     {
    73         scanf("%d", &n);
    74         memset(dp, 0, 30000*sizeof(dp[0]));
    75         len[0] = 1;
    76         for(i = 1; i <= n; i++)
    77         {
    78             scanf("%s", a[i]);
    79             len[i] = strlen(a[i]);
    80             c[i] = len[i] - 1;
    81         }
    82         printf("%d
    ", LCS());           /* 进行倒推 */
    83     }
    84 }
    View Code

    公共字串理解的还不是很深刻  留代码= =、

     
  • 相关阅读:
    [原]写项目方案书的六字方针
    [原]简述Field,Attribute,Property的区别
    [原]Excel(电子表格)中的大写变成小写
    [原]滚动的图片或文字(有缝)
    [原]按字母索引(asp版)
    [原]sql语句上一篇,下一篇
    [原]选中行后高亮显示
    自定义报表开发、使用手册
    男人必须终身牢记的一句话
    在sqlplus中操作blob和clob
  • 原文地址:https://www.cnblogs.com/Silence-AC/p/3272947.html
Copyright © 2011-2022 走看看