一道LIS裸题,求LIS的长度,貌似用n^2的算法会超时,这里用nlogn的贪心。AC代码:
思路如下:开辟一个栈a,每次取一个栈顶元素pop与读到的数n作比较,如果n>pop,则置于栈顶;如果n<pop,则与栈中第一个比n大的数替换。最后读取结束时,栈的长度就是LIS的长度。
import java.util.Scanner;
public class Main
{
static Scanner scan=new Scanner(System.in);
public static void main(String[] args)
{
while(scan.hasNext())
{
int n=scan.nextInt();
long a[]=new long[n+1];//a数组记录读取到的元素
long alen[]=new long[a.length];//用alen数组模拟一个栈
for(int i=1;i<a.length;i++)
a[i]=scan.nextLong();
int pop=1; alen[1]=a[1];//pop代表栈顶元素的位置,最后输出pop即为LIS的值
for(int i=2;i<a.length;i++)
{
if(a[i]>alen[pop])//读取到的数比栈顶元素大
{
alen[pop+1]=a[i];
pop++;
}
if(a[i]<alen[pop])//读取到的数比栈顶元素小
{
for(int k=pop;k>0;k--)//线性查找
if(alen[k-1]<a[i])
{
alen[k]=a[i];
break;
}
}
}
System.out.println(pop);
}
}
}
一道LCS裸题,这题只要求LCS的长度,直接用二维数组做的。AC代码:
思路如下:两个序列X,Y。dp[i][j]表示X的第前 i 项与Y的前 j 项的LCS的长度。如果第 i 项与第 j 项相同,则dp[i][j]=dp[i-1][j-1]+1,如果不相同,则dp[i][j]=Math.max(dp[i-1][j], dp[i][j-1])。
唔,这就是LCS的状态转移方程,我懒得合并了。
import java.util.Scanner;
public class Main
{
static Scanner scan=new Scanner(System.in);
public static void main(String[] args)
{
while(scan.hasNext())
{
String x=scan.next(), y=scan.next();
int lx=x.length(), ly=y.length();
char X[]=new char[lx+1], Y[]=new char[ly+1];
for(int i=1;i<X.length;i++)
X[i]=x.charAt(i-1);
for(int i=1;i<Y.length;i++)
Y[i]=y.charAt(i-1);
int dp[][]=new int[X.length][Y.length];
for(int i=1;i<X.length;i++)
{
for(int j=1;j<Y.length;j++)
{
if(X[i]==Y[j])//如果第 i 项和第 j 项相同
dp[i][j]=dp[i-1][j-1]+1;
else//如果不同
dp[i][j]=Math.max(dp[i-1][j], dp[i][j-1]);
}
}
System.out.println(dp[X.length-1][Y.length-1]);
}
}
}