題目地址:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1576
題目大意:
給定兩個[1,n*n]範圍內的序列,找到其中的LCS,看似很經典的LCS問題。但是,LCS的時間複雜度爲O(pq),在本題中,爲O(n^4),直接用LCS的想法,會超時。注意到每個序列中的數不會有重複,可以這樣處理:給第一個序列中出現的數字從1開始編號。第二個序列中對應的數字給予相應的編號,沒有出現的數字編號爲0,問題轉化爲求序列二中的LIS,可以O(qlgq)的複雜度解決
超時代碼(LCS):
import java.util.*;
public class Main {
static int[] line1 = null;
static int[] line2 = null;
static int[][] ans = null;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int t = in.nextInt();
while((t--)>0)
{
int n = in.nextInt();
int p = in.nextInt();
line1 = new int[p+2];
int q = in.nextInt();
line2 = new int[q+2];
ans = new int[p+2][q+2];
for(int i=1;i<p+2;i++)
line1[i] = in.nextInt();
for(int j=1;j<q+2;j++)
line2[j] = in.nextInt();
for(int i=0;i<p+2;i++)
ans[i][0]=0;
for(int j=0;j<q+2;j++)
ans[0][j]=0;
int max = -1;
for(int i=1;i<p+2;i++)
for(int j=1;j<q+2;j++)
{ if(line1[i]==line2[j])
ans[i][j]=ans[i-1][j-1]+1;
else
ans[i][j]=(ans[i][j-1]>ans[i-1][j])?ans[i][j-1]:ans[i-1][j];
if(ans[i][j]>max) max = ans[i][j];
}
System.out.print("Case "+t+": ");
System.out.println(max);
}
in.close();
}
}
AC代碼(LIS):
import java.util.*;
public class Main_New {
static int[] princess = null;
static int[] mat = null;
static int lowerbound(int[] array,int fromIndex,int toIndex,int key)
{
int l=fromIndex,r=toIndex;
int m;
while(l<r)
{
m = l+(r-l)/2;
if(array[m]<key)
l = m+1;
else
r = m;
}
return r;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int t = in.nextInt();
int round = 0;
while(t>(round++)){
int n = in.nextInt();
mat = new int[n*n+1];
int p = in.nextInt();
int q = in.nextInt();
princess = new int[q+2];
for(int i=1;i<=p+1;i++){
int temp = in.nextInt();
mat[temp] = i;
}
for(int i=1;i<=q+1;i++){
int temp = in.nextInt();
princess[i] = mat[temp];
}
int ans = 0;
int[] d = new int[q+2];
int flag = 1,index = 1;
for(int i=1;i<=q+1;i++){
if(princess[i] == 0) continue;
if(flag == 1)
{ d[1] = princess[i];
flag = 0;
}
else
{
if(princess[i]>d[index]){
index++;
d[index]=princess[i];
}
else
{
int j = lowerbound(d,1,index+1,princess[i]);
d[j] = princess[i];
}
}
}
System.out.println("Case "+round+": "+index);
}
}
}