线性dp

先行dp题目: 牛客dp专题 AcWing线性dp专题

import java.util.Scanner;

/**
 * 最长公共子序列
 *
 * 给定两个字符串 s1 和 s2,长度为 n 和 m  。求两个字符串最长公共子序列的长度。
 * 所谓子序列,指一个字符串删掉部分字符(也可以不删)形成的字符串。
 * 例如:字符串 "arcaea" 的子序列有 "ara" 、 "rcaa" 等。但 "car" 、 "aaae" 则不是它的子序列。
 * 所谓 s1 和 s2 的最长公共子序列,即一个最长的字符串,它既是 s1 的子序列,也是 s2 的子序列。
 * 数据范围 : 1<= m,n<=1000 1≤m,n≤1000 。保证字符串中的字符只有小写字母。
 *
 * 5 6
 * abcde
 * bdcaaa
 *
 * 2
 */
public class 线性dp {
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        int m=sc.nextInt();
        String s1=sc.next();
        String s2=sc.next();
        //定义dp数组,dp[i][j]表示s1的前i+1个字符和s2的前j+1个字符可以匹配的最多的子序列的个数
        int[][] dp=new int[n][m];
        dp[0][0]=s1.charAt(0)==s2.charAt(0)?1:0;
        //初始化边界值
        for(int i=1;i<n;i++){
            if(dp[i-1][0]==1){
                dp[i][0]=1;
            }else{
                dp[i][0]=s1.charAt(i)==s2.charAt(0)?1:0;
            }
        }
        //初始化边界值
        for(int j=1;j<m;j++){
            if(dp[0][j-1]==1){
                dp[0][j]=1;
            }else{
                dp[0][j]=s1.charAt(0)==s2.charAt(j)?1:0;
            }
        }
        //dp状态转移,状态转移方程考虑相等和不想等两种情况
        for(int i=1;i<n;i++){
            for(int j=1;j<m;j++){
                if(s1.charAt(i)==s2.charAt(j)){
                    dp[i][j]=dp[i-1][j-1]+1;
                }else{
                    dp[i][j]=Math.max(dp[i-1][j],dp[i][j-1]);
                }
            }
        }
        System.out.println(dp[n-1][m-1]);
    }
}

全部评论

相关推荐

07-14 13:37
重庆大学 C++
点赞 评论 收藏
分享
仁者伍敌:难怪小公司那么挑剔,让你们这些大佬把位置拿了
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务