1 solutions

  • 2
    @ 2024-4-6 17:10:16

    A1476 最长公共子序列LCS

    思路老师讲过了,不过多赘述,具体看实操

    #include<bits/stdc++.h>
    using namespace std;
    int dp[4016][4016];//dp数组,dp[a][b]表示第一个序列的第一~第a个数组成的子序列与第二个序列的第一——第b个数组成的子序列的LCS长度(怎么感觉语法有点绕?)
    string s,t,ans="";//因为我们最后要根据dp数组推回,所以我们需要提前备好字符串ans
    int main(){
    	cin>>s>>t;//输入两个字符串
    	int n=s.length();//长度
    	int m=t.length();
    	dp[0][0]=0;//当两个字符串长度均为0时,不用说,LCS肯定为0
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=m;j++){
    			if(s[i-1]==t[j-1]){//这里可以省去将字符串整体后移一位这一步
    				dp[i][j]=dp[i-1][j-1]+1;//若相同,则LCS长度+1
    			}
    			else{
    				dp[i][j]=max(dp[i-1][j],dp[i][j-1]);//自己靠不住了,找个大的连上
    			}
    		}
    	}
    	int i=n,j=m;
    	while(i&&j){
    		if(s[i-1]==t[j-1]){
    			ans=s[i-1]+ans;
    			i--;j--;//如果等于,那么毫无疑问,这里就是LCS的一部分(注意不要把s[i-1]和ans写反,不然还得字符串逆序),再两个字符串同时逆推
    		}
    		else if(dp[i-1][j]==dp[i][j]){
    			i--;//如果上面两者相等,说明i-1时和i时是等效的,因此可以直接过渡
    		}
    		else if(dp[i][j-1]==dp[i][j]){
    			j--;//道理同上
    		}
    	}//根据dp数组来推,当i,j还不为0时,LCS所包含的字符总有以上三种情况
    	cout<<ans<<endl;//输出(endl可以不加)
    	return 0;
    }
    

    copy一次一个赞,如果这个题解对你有帮助的话,也不妨点个赞啊o( ̄▽ ̄)d

    • 1

    Information

    ID
    1050
    Time
    1000ms
    Memory
    256MiB
    Difficulty
    6
    Tags
    (None)
    # Submissions
    45
    Accepted
    15
    Uploaded By