码迷,mamicode.com
首页 > 其他好文 > 详细

tyvj2030 题解

时间:2014-08-12 00:01:53      阅读:473      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   io   for   ar   

 

 

给出两个由数字和字母组成的非空字符串ST,求:

1ST的最长公共子序列的长度。

2ST的本质不同的非空公共子序列的个数。

3ST的各种长度的本质不同的非空公共子序列的个数。

思考过程:考场上,果断只会第一问,但是听完题解后,发现事实上他们的思想和第一问是一致的。(此题解借鉴讲题解人)

首先考虑第二问,设dp(i,j)表示s串的前i位和t串的前j位,分两种情况讨论

若s[i]=s[j],则直接把这个字符接在后面,有接和不接两种则dp(i,j)=dp(i-1,j-1)*2,但是我们需要将此结果减去dp(u-1,v-1)其中uv是ij最近相同字符, 考虑dp[u-1][v-1]对应集合中的串x,记S[i]=c,则x,xc∈dp[u][v],则x,xc∈dp[i-1][j-1]。串xc就会在dp[i][j]的集合中出现两遍。

若是s[i]!=s[j],则dp(i,j)=dp(i,j-1)+dp(i-1,j)-dp(i-1,j-1)

这样就解决了第二问,而第三问就是在第二问上加一维,k为长度,dp方程则是一模一样。

bubuko.com,布布扣
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 using namespace std;
 6 string a,b;
 7 int f[305][305];
 8 int g[305][305][305];
 9 int prea[305],preb[305];
10 int ans;
11 const int MOD=1048576;
12 const int SIE = 0xFFFFF;
13 int n,m;
14 int ss;
15 int main()
16 {
17 //    freopen("common5.in","r",stdin);
18 //    freopen("common5.out","w",stdout);
19     cin>>a;cin>>b;
20     n=a.size();
21     m=b.size();
22     a=0+a;
23     b=0+b;
24     for(int i=1;i<=n;i++)
25     {
26         for(int j=1;j<=m;j++)
27         {
28             if(a[i]==b[j])f[i][j]=f[i-1][j-1]+1;
29             f[i][j]=max(f[i][j],f[i-1][j]);
30             f[i][j]=max(f[i][j],f[i][j-1]);
31         }
32     }
33     printf("%d\n",f[n][m]);
34     ss=f[n][m];
35     for(int i=1;i<=n;i++)
36     {
37         int j=i-1;
38         while(j>0 && a[j]!=a[i])j--;
39         prea[i]=j;
40     //    cout<<j;
41     }
42     for(int i=1;i<=m;i++)
43     {
44         int j=i-1;
45         while(j>0 && b[j]!=b[i])j--;
46         preb[i]=j;
47         //cout<<j;
48     }
49     for(int i=0;i<=n;i++)
50     {
51         for(int j=0;j<=m;j++)
52         {
53             g[i][j][0]=1;
54         }
55     }
56     for(int i=1;i<=n;i++)
57     {
58         for(int j=1;j<=m;j++)
59         {
60             if(a[i]==b[j])
61             {
62                 for(int k=1;k<=ss;k++)
63                 {
64                     g[i][j][k]=(g[i-1][j-1][k]+g[i-1][j-1][k-1])&SIE;
65                 }
66                 if(prea[i] && preb[j])
67                 {
68                     for(int k=1;k<=ss;k++)
69                     {
70                         g[i][j][k]=(g[i][j][k]-g[prea[i]-1][preb[j]-1][k-1])&SIE;
71                     }
72                 }
73             }
74             else
75             {
76                 for(int k=1;k<=ss;k++)
77                 {
78                     g[i][j][k]=(g[i-1][j][k]+g[i][j-1][k]-g[i-1][j-1][k])&SIE;
79                     //cout<<i<<" "<<j<<" "<<k<<" "<<g[i][j][k]<<endl;
80                 }
81             }
82         }
83     }
84     int sum=0;
85     for(int i=1;i<=ss;i++)sum=(sum+g[n][m][i])%MOD;
86     printf("%d\n",sum);
87     for(int i=1;i<=ss;i++)printf("%d\n",g[n][m][i]);
88     return 0;
89 }
View Code

 

tyvj2030 题解,布布扣,bubuko.com

tyvj2030 题解

标签:style   blog   http   color   os   io   for   ar   

原文地址:http://www.cnblogs.com/sillygirl/p/3905623.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!