zoukankan      html  css  js  c++  java
  • 【tyvj】【dp】最长公共子序列(LCS)

    描述

    一个字符串A的子串被定义成从A中顺次选出若干个字符构成的串。如A=“cdaad",顺次选1,3,5个字符就构成子串"cad",现给定两个字符串,求它们的最长共公子串。

    输入格式

    第一行两个字符串用空格分开。

    输出格式

    最长子串的长度。

    思路

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    #define INF 0xffffffff
    #define REP(a,b) for(int i=a;i<=b;i++)
    #define RES(a,b) memset(a,b,sizeof(a))
    using namespace std;
    
    //dp[i][j]代表第一段序列取前i个字符,第二段序列取前j个字符的lcs长度
    //如果c1[i]==c2[j],dp[i][j]=dp[i-1][j-1]+1
    //即两个位置上的字符相同,可以直接在之前的lcs上加上这个字符 
    //如果c1[i]!=c2[j],dp[i][j]=max{dp[i-1][j],dp[i][j-1]} 
    //如果不同,只能去掉一个字符之后,看哪个更大就把它作为dp[i][j]的值 
    
    char c1[2010],c2[2010],dp[2010][2010];
    int l1=3000,l2=3000;//l1代表c1长度,l2代表c2长度 
    
    bool same(int a, int b){
    	if(c1[a]==c2[b]) return true;
    	return false;
    } 
    
    int main(){
    	RES(c1,0); RES(c2,0); RES(dp,0);
    	scanf("%s%s",c1,c2);
    	for(int i=0;i<=l1;i++){
    		if(c1[i]!=0) for(int j=0;j<=l2;j++){
    			if(c2[j]!=0){
    				if(same(i,j)){
    					if(i==0||j==0) dp[i][j]++;
    					else dp[i][j]=dp[i-1][j-1]+1;
    				}
    				else{
    					if(i!=0) dp[i][j]=max(dp[i-1][j],dp[i][j]);
    					if(j!=0) dp[i][j]=max(dp[i][j-1],dp[i][j]);
    				}
    			}
    			else {
    				l2=j-1; break;
    			}
    		}
    		else {
    			l1=i-1; break;
    		}
    	}
    	printf("%d",dp[l1][l2]);
    	return 0;
    }

  • 相关阅读:
    PKU 学生的反馈 20091
    PKU 学生的反馈 2009 –2
    中国队有进步
    刚发现博客园又遇到了问题
    今日计划
    Delphi中使用多线程
    在老ASP中使用对象的对象生存期问题
    ASP与Javascript
    ASP & VBScript的错误处理
    对前一段时间学习网络和多线程编程的总结
  • 原文地址:https://www.cnblogs.com/leotan0321/p/6081420.html
Copyright © 2011-2022 走看看