hdu 5282 Senior's String

来源:互联网 发布:qq空间红人软件 编辑:程序博客网 时间:2024/06/13 02:37

        两个串x和y,它们的LCS长度为l,问x所有长度为l的子串中,有多少个y的子串(包括空串)。

        dp。首先是求LCS,经典dp问题。然后再进行一次dp,ans(i,j)表示x前i个字符和y前j个字符的答案。状态转移是这样的,对于x的第i个字符,考虑取和不取两种情况。不取的情况比较简单,如果x的第i个字符对LCS没有贡献,那么就可以不取。如果要取x的第i个字符,找到y中前j个字符与之匹配的最后一个位置,如果dp(i-1,pos-1)+1=dp(i,j),就说明可以取。详见代码。


//#include <bits/stdc++.h>  #include <string.h>#include <stdio.h>#include <iostream>#include <stdlib.h>#include <memory.h>#include <cmath>#include <algorithm>using namespace std;  #define ll long longconst int mod = 1e9+7;char a[1010];char b[1010];int dp[1010][1010];int ans[1010][1010];int last[200];int main(){int t;cin>>t;while(t--){memset(dp,0,sizeof(dp));memset(ans,0,sizeof(ans));memset(last,0,sizeof(last));scanf("%s%s",a+1,b+1);int lena=strlen(a+1);int lenb=strlen(b+1);for(int i=0;i<=max(lena,lenb);i++){ans[i][0]=1;ans[0][i]=1;}for(int i=1;i<=lena;i++){for(int j=1;j<=lenb;j++){if(a[i]==b[j]){dp[i][j]=dp[i-1][j-1]+1;}dp[i][j]=max(dp[i][j],dp[i-1][j]);dp[i][j]=max(dp[i][j],dp[i][j-1]);}}for(int i=1;i<=lena;i++){memset(last,0,sizeof(last));for(int j=1;j<=lenb;j++){if(dp[i-1][j]==dp[i][j]){ans[i][j]=ans[i-1][j];}last[b[j]]=j;int pos=last[a[i]];if(pos && dp[i-1][pos-1]+1==dp[i][j]){ans[i][j]+=ans[i-1][pos-1];}ans[i][j]%=mod;}}cout<<ans[lena][lenb]<<endl;}return 0;}


0 0
原创粉丝点击