本文主要是介绍单调递增最长子序列--动态规划的经典题目,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
地址:http://acm.nyist.net/JudgeOnline/problem.php?pid=17
单调递增最长子序列
时间限制:3000 ms | 内存限制:65535 KB
难度:4
- 描述
- 求一个字符串的最长递增子序列的长度
如:dabdbf最长递增子序列就是abdf,长度为4- 输入
- 第一行一个整数0<n<20,表示有n个字符串要处理
随后的n行,每行有一个字符串,该字符串的长度不会超过10000 输出 - 输出字符串的最长递增子序列的长度 样例输入
-
3 aaa ababc abklmncdefg
样例输出 -
1 3 7
- 第一行一个整数0<n<20,表示有n个字符串要处理
思路:就是分1个的时候,有多少个最长递增的,2个的时候,有多少个最长递增的,3个的时候,有多少个最长递增的,4个的时候,有多少个最长递增的......
用下列的方式进行存储,最长子序列的状态
public static void longestIncreasingSubsequenceDp2(String str){char[] chs=str.toCharArray();int length=chs.length;int i,j,k,index;int[] L=new int[length];int[][] x=new int[length][length];for(i=0;i<length;i++){L[i]=1;x[i][0]=chs[i]; //初始化,最长递增子序列长度为1}for(i=0;i<length;i++){int max=1;for(j=i-1;j>=0;j--){if(chs[j]<chs[i]&&max<L[j]+1){max=L[j]+1;L[j]=max;for(k=0;k<max-1;k++) //存储最长递增子序列x[i][k]=x[j][k];x[i][max-1]=chs[i]; //找到当前最长的子序列后,进行横向保存序列}}}for(index=0,i=1;i<length;i++) //找到最长的下标if(L[index]<L[i])index=i;System.out.print("最长递增子序列是:");for(i=0;i<L[index];i++)System.out.println(x[index][i]+" ");}
即:找到当前最长的,就进行横向保存序列。x[i][j],x[i][j+1],....
最后附上代码:
import java.util.Scanner;public class Main {public static void main(String[] args){Scanner cin=new Scanner(System.in);int n=cin.nextInt();while(n-->0){String str=cin.next();longestIncreasingSubsequenceDp1(str);}}//253 371 public static void longestIncreasingSubsequenceDp1(String str){char[] chs=str.toCharArray();int length=chs.length;int [] dp=new int[length];for(int i=0;i<length;i++){dp[i]=1;for(int j=0;j<i;j++){if(chs[j]<chs[i]&&dp[i]<dp[j]+1)dp[i]=dp[j]+1;}}int sum=0;for(int i=0;i<length;i++){if(dp[i]>sum)sum=dp[i];}System.out.println(sum);}//保存了最长的子序列public static void longestIncreasingSubsequenceDp2(String str){char[] chs=str.toCharArray();int length=chs.length;int i,j,k,index;int[] L=new int[length];int[][] x=new int[length][length];for(i=0;i<length;i++){L[i]=1;x[i][0]=chs[i]; //初始化,最长递增子序列长度为1}for(i=0;i<length;i++){int max=1;for(j=i-1;j>=0;j--){if(chs[j]<chs[i]&&max<L[j]+1){max=L[j]+1;L[j]=max;for(k=0;k<max-1;k++) //存储最长递增子序列x[i][k]=x[j][k];x[i][max-1]=chs[i]; //找到当前最长的子序列后,进行横向保存序列}}}for(index=0,i=1;i<length;i++) //找到最长的下标if(L[index]<L[i])index=i;System.out.print("最长递增子序列是:");for(i=0;i<L[index];i++)System.out.println(x[index][i]+" ");}}
这篇关于单调递增最长子序列--动态规划的经典题目的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!