HDU 4681 String 解题报告
2013-08-15 21:18
357 查看
2013
暑假多校训练 8 总结
题目
题意:
有三个字符串ABC,现在要求一个最长的字符串D,使得:
1、D是A的子序列。
2、D是B的子序列。
3、C是D的子串。
输出D的长度。
题解:
首先对于A,求以J为结尾时,最大的I,使得C是A[i]~A[j]的子序列。B同理。
然后枚举A、B各自包含C的区间,那么两个区间外的位置用LCS计算能在C两端加的字符数。
有点卡常数,T了两次,还是自己写得不够好吧。
暑假多校训练 8 总结
题目
题意:
有三个字符串ABC,现在要求一个最长的字符串D,使得:
1、D是A的子序列。
2、D是B的子序列。
3、C是D的子串。
输出D的长度。
题解:
首先对于A,求以J为结尾时,最大的I,使得C是A[i]~A[j]的子序列。B同理。
然后枚举A、B各自包含C的区间,那么两个区间外的位置用LCS计算能在C两端加的字符数。
有点卡常数,T了两次,还是自己写得不够好吧。
//Time:593ms //Memory:10520KB #include <cstdio> #include <cstdlib> #include <cstring> #include <queue> #include <algorithm> using namespace std; #define MAXN 1010 #define INF 1000000007 int lcdp[2][MAXN][MAXN]; int dp[MAXN][MAXN]; int mbegin[2][MAXN]; char sta[MAXN],stb[MAXN],stc[MAXN]; void rever(char s[],int len) { for(int i=0,j=len-1;i<j;++i,--j) swap(s[i],s[j]); } void cal(char s1[],char s2[],int arr[],int len1,int len2) { memset(dp,-1,sizeof(dp)); for(int i=0;i<len1;++i) for(int j=0;j<len2;++j) { dp[i][j]=max(dp[i][j],i>0?dp[i-1][j]:-1); if(s1[i]==s2[j]) { if(j==0) dp[i][j]=i; dp[i+1][j+1]=max(dp[i+1][j+1],dp[i][j]); } } for(int i=0;i<=len1;++i) arr[i]=dp[i][len2]; } void cal2(char s1[],char s2[],int arr[][MAXN],int len1,int len2) { for(int i=0;i<len1;++i) for(int j=0;j<len2;++j) arr[i][j]=0; for(int i=0;i<len1;++i) arr[i][0]=max((int)(s1[i]==s2[0]),i?arr[i-1][0]:0); for(int i=1;i<len2;++i) arr[0][i]=max((int)(s1[0]==s2[i]),arr[0][i-1]); for(int i=1;i<len1;++i) for(int j=1;j<len2;++j) { arr[i][j]=max(arr[i-1][j],arr[i][j-1]); if(s1[i]==s2[j]) arr[i][j]=max(arr[i][j],arr[i-1][j-1]+1); } } int main() { //freopen("/home/moor/Code/1006.txt","r",stdin); int ncase,la,lb,lc,ans; scanf("%d",&ncase); for(int h=1;h<=ncase;++h) { scanf("%s%s%s",sta,stb,stc); la=strlen(sta);lb=strlen(stb);lc=strlen(stc); ans=0; cal(sta,stc,mbegin[0],la,lc); cal(stb,stc,mbegin[1],lb,lc); cal2(sta,stb,lcdp[0],la-lc+1,lb-lc+1); rever(sta,la); rever(stb,lb); cal2(sta,stb,lcdp[1],la-lc+1,lb-lc+1); for(int i=1;i<=la;++i) if(mbegin[0][i]>=0) for(int j=1;j<=lb;++j) if(mbegin[1][j]>=0) { int t1=mbegin[0][i],t2=mbegin[1][j]; ans=max(ans,((t1>0&&t2>0)?lcdp[0][t1-1][t2-1]:0)+ ((i<la&&j<lb)?lcdp[1][la-i-1][lb-j-1]:0)); } printf("Case #%d: %d\n",h,ans+lc); } return 0; }
相关文章推荐
- HDU 4821 String 解题报告(哈希)
- HDU 1394 Minimum Inversion Number 解题报告
- hdu 4681 string
- hdu 1257 最少拦截系统 解题报告
- hdu 2091 空心三角形 解题报告
- hdu 1181 变形课 解题报告
- poj 1734 Sightseeing trip hdu 1599 find the mincost route 最小环 解题报告
- hdu 2242 考研路茫茫——空调教室 【Tarjan缩点+树上DP】 解题报告
- hdu 2460 Network Tarjan缩点+LCA 解题报告
- HDU 2546 饭卡(01背包) 解题报告
- BestCoder7 1002 Little Pony and Alohomora Part I(hdu 4986) 解题报告
- HDU 1217 Arbitrage 解题报告
- HDU 4632 Palindrome subsequence 解题报告
- HDU 5828 Rikka with Sequence 解题报告
- Hdu 2088之解题报告
- hdu 1000 A + B Problem 的解题报告
- hdu 1875 畅通工程再续 解题报告
- hdu 2062 Subset sequence 解题报告
- HDU 4989 Summary BestCoder Round #8 解题报告
- Hdu 3037 Saving Beans 卢卡斯定理 解题报告