hdu 5282 Senior's String
2015-07-14 20:51
453 查看
两个串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),就说明可以取。详见代码。
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 long const 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; }
相关文章推荐
- TJU-3848 Game(矩阵乘法快速幂)
- fork进程创建
- 005-android studio的安装
- #笔记#圣思园 JavaWeb 第39讲——Filter过滤器
- GNOME 桌面为什么这么好?
- 如何自己编写Makefile(高级篇)
- cdlinux可以安装在c盘
- background-clip 属性
- iOS 开发中手机号 价格金额 有效性判断
- Hibernate(五)映射集合属性及排序
- 第二周编程作业 时间换算
- NSArray, NSNumber, NSValue, NSSet, 数组排序
- 如何自己编写Makefile
- C语言程序设计4、5章
- 行为型模式-解释器
- UVA 6859 Points
- 素材网站
- leetcode 031 —— Next Permutation
- Permutations
- 【Android】AudioRecord--录音并将 PCM文件转为WAV