importjava.util.*;importjava.io.*;publicclassMain{staticintN=510;staticint INF =(int)(1e9);staticint[][] a =newint[N][N];staticint[][] f =newint[N][N];publicstaticvoidmain(String[] args)throwsIOException{BufferedReader in =newBufferedReader(newInputStreamReader(System.in));String str1 = in.readLine();int n =Integer.parseInt(str1);for(int i =1; i <= n; i++){String[] str2 = in.readLine().split(" ");for(int j =1; j <= i; j++){
a[i][j]=Integer.parseInt(str2[j -1]);}}// 初始化fijfor(int i =0; i <= n ; i++){for(int j =0; j <= i +1; j++){// 此处之所以 j 会遍历到 i + 1 是因为在 j = i的时候// a[i][j] 的右上角是没有数值的,但是因为状态转换公式会遍历到右上角,并且不能影响后面的值// 因此也需要进行负无穷初始化
f[i][j]=-INF;}}// 初始化第一行数据
f[1][1]= a[1][1];for(int i =2; i <= n; i++){// 从第二行开始进行状态转换for(int j =1; j <= i; j++){// 状态转换方程将集合分成了左上角和右上角的路线来进行处理
f[i][j]=Math.max(f[i -1][j -1]+ a[i][j], f[i -1][j]+ a[i][j]);}}int result =-INF;for(int j =1; j <= n; j++){// 因为最后有很多个出口可以走,我们需要对最后一行的出口进行数值比较才可以最终得到路径最大值
result =Math.max(result, f[n][j]);}System.out.println(result);}}
二、最长上升子序列
1、题目内容
2、状态划分
1)状态编号 f[i]
状态 f[i] 表示其所有以第 i 个数结尾的上升子序列
2)状态划分
3、题解
importjava.util.*;publicclassMain{staticintN=1010;staticint[] a =newint[N];staticint[] f =newint[N];publicstaticvoidmain(String[] args){Scanner in =newScanner(System.in);int n = in.nextInt();for(int i =1; i <= n; i++){
a[i]= in.nextInt();}for(int i =1; i <= n; i++){
f[i]=1;// f[i]=1是对最长子序列长度做初始化,最小的子序列就是本身,如果需要增加后面的max会进行处理for(int j =1; j < i; j++){if(a[j]< a[i]){
f[i]=Math.max(f[i], f[j]+1);// i 前面的 j 需要需要满足小于条件,然后才可以加入上升子序列长度}}}int res =0;for(int i =1; i <= n; i++){
res =Math.max(res, f[i]);// 找出所有位置中最长的子序列,也就相当于max(max())}System.out.println(res);}}
三、最长公共子序列
1、题目内容
2、状态划分
1)状态编号 f[i][j]
f[i][j] 表示所有在第一个序列的第 i 个字母中出现,且在第二个序列的前 j 个子母钟出现的子序列。
2)状态划分
3、题解
importjava.util.*;importjava.io.*;publicclassMain{staticintN=1010;staticint[][] f =newint[N][N];publicstaticvoidmain(String[] args)throwsIOException{BufferedReader in =newBufferedReader(newInputStreamReader(System.in));String[] str1 = in.readLine().split(" ");int n =Integer.parseInt(str1[0]);int m =Integer.parseInt(str1[1]);String aStr = in.readLine();String bStr = in.readLine();char[] a = aStr.toCharArray();char[] b = bStr.toCharArray();for(int i =1; i <= n; i++){for(int j =1; j <= m; j++){
f[i][j]=Math.max(f[i -1][j], f[i][j -1]);// ai与bj至少有一个选择加入公共子序列了,也就包括了一个都没有加入子序列if(a[i -1]== b[j -1]){
f[i][j]=Math.max(f[i][j], f[i -1][j -1]+1);// 两个都加入子序列,则长度加一}}}System.out.println(f[n][m]);}}