最长非上升子序列
2012-06-04 11:38
211 查看
问题描述:
给定一个序列:X1 X2 X3 X4 X5 X6......Xn,试图找到一个最长的子序列,Xi1 Xi2 Xin,使得i1 < i2 < i3 ...而且Xi1 < Xi2 < Xi3......。举个例子:48 65 34 29 64 38 89
有一种非常简单的做法,能够非常简单的计算出所要序列的长度,但是无法给出序列。过程如下
48
65
65 34
65 34 29
65 64 29
65 64 38
89 64 38
因此最长非上升子序列长度为3,代码如下:
Java
import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class SubSeqDesc { public static void main(String[] args) { Scanner sin = new Scanner(System.in); List<Integer> maxList = new ArrayList<Integer>(32); int ele = 0; if ((ele = sin.nextInt()) != -1) { maxList.add(ele); while ((ele = sin.nextInt()) != -1) { if (maxList.get(maxList.size() - 1) >= ele) { maxList.add(ele); } else { int i = 0; while (maxList.get(i) >= ele) i++; maxList.set(i, ele); } } System.out.println("the longest subsequence' length is " + maxList.size()); } else { System.out.println("no sequence..."); } } }
另外有一种动态规划的方法。记opt[i](i = 0...len)表示以array[i]为尾的满足条件的序列,那么最终所要求的序列必定在opt[i]中的最大值,也就是序列最大长度。代码如下:
Java
import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class SubSeqDesc2 { public static void main(String[] args) { Scanner sin = new Scanner(System.in); List<Integer> maxList = new ArrayList<Integer>(32); int ele = 0; while ((ele = sin.nextInt()) != -1) { maxList.add(ele); } int len = maxList.size(); if (len == 0) { System.out.println("no sequence..."); } else { Integer[] seq = new Integer[len]; maxList.toArray(seq); int[] opt = new int[len]; opt[0] = 1; for(int i = 1; i < len; i++){ opt[i] = 1; for(int j = 0; j < i; j++){ if(seq[j] >= seq[i] && opt[j] + 1 > opt[i]){ opt[i] = opt[j] + 1; } } } int result = opt[0]; for(int i = 1; i < len; i++){ if(result < opt[i]){ result = opt[i]; } } System.out.println("the longest subseq is " + result); } } }
根据第二个做法,可以通过加入新的前向数组来输出一个最长的子序列:
Java
import java.util.ArrayList;import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
public class SubSeqDesc3 {
public static void main(String[] args) {
Scanner sin = new Scanner(System.in);
List<Integer> maxList = new ArrayList<Integer>(32);
int ele = 0;
while ((ele = sin.nextInt()) != -1) {
maxList.add(ele);
}
int len = maxList.size();
if (len == 0) {
System.out.println("no sequence...");
} else {
Integer[] seq = new Integer[len];
int[] previous = new int[len];
maxList.toArray(seq);
int[] opt = new int[len];
opt[0] = 1;
previous[0] = -1;
for(int i = 1; i < len; i++){
opt[i] = 1;
previous[i] = -1;
for(int j = 0; j < i; j++){
if(seq[j] >= seq[i] && opt[j] + 1 > opt[i]){
opt[i] = opt[j] + 1;
previous[i] = j;
}
}
}
int result = 0;
for(int i = 1; i < len; i++){
if(result < opt[i]){
result = i;
}
}
System.out.println("length:" + opt[result]);
System.out.print("subsequence:");
LinkedList<Integer> stack = new LinkedList<Integer>();
do{
stack.push(result);
result = previous[result];
}while(result != -1);
while(!stack.isEmpty()){
System.out.print(seq[stack.pop()] + " ");
}
System.out.println();
}
}
}
相关文章推荐
- hdu 1160 dp (二维最长上升子序列 记录路径
- POJ 1631 —— Bridging signals 最长上升子序列
- HDU 1423 最长公共字串+上升子序列
- 波浪子序列 Wavio Sequence UVA10534 动态规划 最长上升子序列变形
- LIS(即最长上升子序列)
- poj2533 Longest Ordered Subsequence(最长上升子序列)
- CODEVS 1576 最长严格上升子序列
- hdu 1025(最长上升子序列)
- caioj1064 最长上升子序列
- 最长上升子序列
- HDU 1025 Constructing Roads In JGShining's Kingdom (简单dp, 最长上升子序列LIS)
- POJ-163--Bridging signals最长上升子序列
- 最长上升子序列
- Codeforces Round #335 (Div. 2)-C Sorting Railway Cars(最长上升子序列)
- LIS最长上升子序列
- SGU 199. Beautiful People(最长上升子序列nlogn LIS)
- 最长上升子序列
- 清橙 A1120 拦截导弹 -- 动态规划(最长上升子序列)
- HDU 1080-Super Jumping! Jumping! Jumping!(LIS最长上升子序列-最大递增子段和)
- 01背包、完全背包、最长上升子序列