题目描述:从a,b俩数组中找出共有的最长子序列,如a={1,2,3,5,6,4,8},b={1,1,2,5,5,3,5,7,6,},其最长公共子序列为{1,2,3,5,6}.

解决方法:动态规划,寻找子问题,可以发现,当前的最长子序列一定等于上一次的加一,否则,就等于上一次的。

即:c[i][j]=0;               当i==0或j==0时

    c[i][j]=c[i-1][j-1]+1.   当a[i]=b[j]时

    c[i][j]=c[i-1][j].       当c[i-1][j]>c[i][j-1]时

    c[i][j]=c[i][j-1].       当c[i][j-1]>c[i][j-1]时

i和j分别表示数组a中前i个和数组b中前j个的最长公共子序列.

代码如下:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 using namespace std;
 5 int longque(int m,int n,int *a,int *b,int **c,int **flag)
 6 {
 7     for(int i=0;i<=n;i++)      //初始化0行0列
 8         c[i][0]=0;             
 9     for(int i=0;i<=m;i++)
10         c[0][i]=0;  
11         
12         int max1=0;
13     for(int i=1;i<=n;i++)             
14     {
15         for(int j=1;j<=m;j++)
16         {
17             if(a[i]==b[j])         //相等时+1,标标记为1
18                {
19                   c[i][j]=c[i-1][j-1]+1;flag[i][j]=1;
20                }
21             else if(c[i-1][j]>c[i][j-1]){        //不相等时,取大的并标记
22                 c[i][j]=c[i-1][j];  flag[i][j]=2;
23             }else{
24                 c[i][j]=c[i][j-1]; flag[i][j]=3;
25             }
26             max1=max(max1,c[i][j]);
27         }
28 
29     }
30 
31      return max1;
32 }
33 void LCS(int i,int j,int **flag,int *a)
34 {
35     if(i==0||j==0)return;
36     if(flag[i][j]==1)          //相等时,为公共最长子序列输出
37     {
38         LCS(i-1,j-1,flag,a);cout<<a[i]<<" ";
39     }else if(flag[i][j]==2)
40     {
41          LCS(i-1,j,flag,a);
42     }else
43     {
44          LCS(i,j-1,flag,a);
45     }
46 }
47 int main()
48 {
49   int n,m;
50   cout<<"俩数组长度分别为"<<endl;
51   cin>>n>>m;
52   int a[n+1];                            
53   int b[m+1];
54   cout<<"输入"<<n<<"个数"<<endl;
55   for(int i=1;i<=n;i++)
56   {
57       cin>>a[i];
58   }
59    cout<<"输入"<<m<<"个数"<<endl;
60   for(int i=1;i<=m;i++)
61   {
62       cin>>b[i];
63   }
64 
65   int *c[n+1],*flag[n+1];        //数组c[i][j],标记数组flag[i][j].
66  for(int i=0;i<n+1;i++)
67   {
68       c[i]=(int *)malloc((m+1)*sizeof(int));
69        flag[i]=(int *)malloc((m+1)*sizeof(int));
70   }
71   cout<<"最长公共子序列为"<<endl;
72   cout<<longque(m,n,a,b,c,flag)<<endl;  //求最长公共子序列长度
73   LCS(n,m,flag,a);                      //打印序列
74 
75 }

 

   

 posted on 2017-09-22 20:50  几缕清风依旧  阅读(611)  评论(0编辑  收藏  举报