UVa 10635 Prince and Princess(JAVA版)

UVa 10635 Prince and Princess

题目大意:LCS

思路如下:这题倒是道很简单的题目,但是我还是挺喜欢的,至少学会了种新方法。求LCS,但是普通n^2的算法会超时,我第一次超时之后百度了下,看了看LCS的时间优化,说是结合LIS的nlogn算法,然后就开始想。挺巧的,但是我感觉我的这个方法只适用于数组元素不重复的情况,刚好符合这个~有需要再改吧。a、b数组分别接受两串数据,然后开一个lcs数组,当a[i]=b[j]时,令lcs[i]=j,然后用nlogn的算法求lcs数组的最大上升子序列(汗,我用来模拟栈的数组名叫lis)~即以a数组的元素序列定义一个顺序(1,2,....,n即等同于数组下标),然后用一个新的数组依次记录b数组中与a数组相同的元素的b的下标(lcs[i]=j),i 是第 i 个a数组元素,j 是第 j 个b数组元素。 

PS:这题对于Java玩家来说,似乎必须用快速io,用快速io在查找时用二分也好,线性也好,都能过;不用快速io怎么都不能过~

AC代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;

public class Main//中间有段用/***/括起来的是nlogn算法的二分查找,也能AC,但是本人用的是后面的线性查找,两者都能AC
{
	static StreamTokenizer in=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
	static PrintWriter out=new PrintWriter(new OutputStreamWriter(System.out));
	
	public static int nextInt()throws IOException {in.nextToken();return (int)in.nval;}
	
	public static void main(String[] args)throws IOException
	{
		int t=nextInt();
		int cas=0;
		while((cas++)<t)
		{
			int n=nextInt();
			int p=nextInt();
			int q=nextInt();
			int a[]=new int[p+2];
			int b[]=new int[q+2];
			
			for(int i=1;i<p+2;i++)
				a[i]=nextInt();//a是记录第一串数据,把a数组中的每个元素顺次构成数组下标
			for(int i=1;i<q+2;i++)
				b[i]=nextInt();//b是记录第二串数据,把b中元素与a比对,有相同的就赋值为
			
			int lcs[]=new int[q+2];
			for(int i=1;i<q+2;i++)
				for(int j=1;j<p+2;j++)
					if(b[i]==a[j])
					{
						lcs[i]=j;
						break;
					}
			
			int pop=1; int lis[]=new int[q+2];
			lis[1]=lcs[1];
			for(int i=2;i<q+2;i++)
			{
				if(lcs[i]>lis[pop])
					lis[++pop]=lcs[i];
				if(lcs[i]<lis[pop])
				{
					/*int min=1,max=pop;
					for(int mid=(min+max)/2;min<=max;mid=(min+max)/2)
					{
						if(lcs[i]>lis[mid] && lcs[i]<lis[mid+1])//if(lcs[i]<lis[mid] && lcs[i]>lis[mid-1])这样也行
						{
							lis[mid+1]=lcs[i];//lis[mid]=lcs[i];
							break;
						}
						if(lcs[i]>lis[mid])
							min=mid+1;
						if(lcs[i]<lis[mid])
							max=mid-1;
						
					}*/
					for(int k=pop;k>0;k--)
						if(lcs[i]>lis[k-1])
						{
							lis[k]=lcs[i];
							break;
						}
				}
			}
			System.out.println("Case "+cas+": "+pop);
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值