COJ1078 最长公共子序列
原题链接:http://122.207.68.93/OnlineJudge/problem.php?id=1078
这道题与双序列的最长公共子序列毫不相干,其本质为单序列的最长上升子序列。
先离散化,然后用一个数组记录每个数字出现的位置(其实只需要记录第一行的序列),那么就可以转换成求最长上升子序列了,这里的上升是相对于某个数字的位置数组来说的(也就是n维的),比如(1,2,1) < (2,3,2),但(2,2,2)<(1,3,3)不成立。然后O(m2)求LIS就行了。
第一次用JAVA,还不是很熟练,不熟悉JAVA机制与优化,代码运行得比较慢。
1 import java.io.BufferedReader; 2 import java.io.IOException; 3 import java.io.InputStream; 4 import java.io.InputStreamReader; 5 import java.io.OutputStream; 6 import java.io.PrintWriter; 7 import java.util.ArrayList; 8 import java.util.HashMap; 9 import java.util.List; 10 import java.util.Scanner; 11 import java.util.StringTokenizer; 12 13 public class Main { 14 15 public static void main(String[] args) { 16 OutputStream outputStream = System.out; 17 Scanner in = new Scanner(System.in); 18 PrintWriter out = new PrintWriter(outputStream); 19 TaskA solver = new TaskA(); 20 solver.solve(in, out); 21 out.close(); 22 } 23 } 24 25 class TaskA { 26 27 public int id; 28 int[] dp = new int[1005]; 29 public HashMap<Integer, Integer> map = new HashMap<Integer, Integer>(); 30 31 public TaskA() { 32 } 33 34 public void init() { 35 id = 0; 36 map.clear(); 37 } 38 39 public void solve(Scanner in, PrintWriter out) { 40 while (in.hasNext()) { 41 init(); 42 int n = in.nextInt(); 43 int m = in.nextInt(); 44 45 Node[] k = new Node[m + 1]; 46 47 for (int j = 1; j <= m; j++) { 48 map.put(in.nextInt(), j); 49 k[j] = new Node(); 50 k[j].list.add(j); 51 } 52 for (int i = 1; i < n; i++) { 53 for (int j = 1; j <= m; j++) { 54 int tmp = in.nextInt(); 55 if (map.get(tmp) != null) 56 k[map.get(tmp)].list.add(j); 57 } 58 } 59 int res = 0; 60 dp[0] = 0; 61 for (int i = 1; i <= m; i++) { 62 if (k[i].list.size() == n) { 63 dp[i] = 1; 64 for (int j = i - 1; j >= 1; j--) { 65 if (k[j].list.size() == n && k[i].compareTo(k[j]) > 0) 66 dp[i] = max(dp[i], dp[j] + 1); 67 } 68 res = max(dp[i], res); 69 } 70 } 71 System.out.println(res); 72 } 73 } 74 75 public int max(int a, int b) { 76 return a > b ? a : b; 77 } 78 } 79 80 class Node implements Comparable<Object> { 81 82 public List<Integer> list; 83 84 public Node() { 85 list = new ArrayList<Integer>(); 86 } 87 88 public int compareTo(Object o) { 89 Node node = (Node) o; 90 int n = node.list.size(); 91 for (int i = 0; i < n; i++) { 92 if (list.get(i).intValue() < node.list.get(i).intValue()) { 93 return -1; 94 } 95 } 96 return 1; 97 } 98 99 } 100 101 class InputReader { 102 public BufferedReader reader; 103 public StringTokenizer tokenizer; 104 105 public InputReader(InputStream stream) { 106 reader = new BufferedReader(new InputStreamReader(stream)); 107 tokenizer = null; 108 } 109 110 public String next() { 111 while (tokenizer == null || !tokenizer.hasMoreTokens()) { 112 try { 113 tokenizer = new StringTokenizer(reader.readLine()); 114 } catch (IOException e) { 115 throw new RuntimeException(e); 116 } 117 } 118 return tokenizer.nextToken(); 119 } 120 121 public int nextInt() { 122 return Integer.parseInt(next()); 123 } 124 }