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 }
View Code
原文地址:https://www.cnblogs.com/huangfeihome/p/3116089.html