思路:
开始会想,直接直接从数组a的第i个开始匹配,b设一个str储存当前位置加1,一个个去匹配不好吗?然后就会发现,因为是不连续的,所以会存在拿与不拿的问题,这个时候就该想到dp了。dp的熟悉套路是
取值情况:两种取值,a的数量和b的数量
dp代表的值:一般情况都是代表直接求的值,这题就是公共子序列的长度。
字符串切割就不说了,找到大写,与前一个截取,存入,更新前一个下标,end
这里记录一下dp[i][j]的思路,肯定是先遍历a的字符串,再在a字符串取一个的情况下对b字符串进行匹配。如果拿到了,那么当前长度的字符串的长度是前一个字符串拿到长度的值+1,如果没拿的话,就看前面dp[i-1][j]大还是dp[i][j-1]大,最后查看两个都遍历完的取值。end
import java.io.*;
import java.util.ArrayList;
public class Main{
static BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
static PrintWriter pw=new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
public static void main(String[] args) throws IOException {
ArrayList a=f(bf.readLine());
ArrayList b=f(bf.readLine());
//dp[i][j]的意思是a选到第i个,b选到第j个的最大子序列长度
//dp[0][0]=0
int[][] dp=new int[a.size()+1][b.size()+1];
for(int i=0;i<a.size();i++) {
for(int j=0;j<b.size();j++) {
if(a.get(i).equals(b.get(j))) {
dp[i+1][j+1]=dp[i][j]+1;
}else {
dp[i+1][j+1]=Math.max(dp[i][j+1], dp[i+1][j]);
}
}
}
pw.print(dp[a.size()][b.size()]);
pw.flush();
}
public static ArrayList f(String a) {
//储存前一个大写字母的位置
int str=0;
ArrayList arraylist=new ArrayList<>();
for(int i=1;i<a.length();i++) {
if(a.charAt(i)<'a') {
String s=a.substring(str,i);
arraylist.add(s);
str=i;
}
}
arraylist.add(a.substring(str,a.length()));
return arraylist;
}
}0.0分
2 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复