我试图解决this practice problem,下面也引用了它。
厨师正计划为DirectiPlex就职典礼举办自助餐, 每个人都被邀请。在他们的路上,每位客人拿起一张纸 包含随机数的纸张(此数字可以重复)。该 然后客人和他们的朋友坐在圆桌旁。 厨师现在决定他想玩游戏。他要求你从你的桌子上挑选一个随机的人,并让他们阅读他们的 数字响亮。然后,围绕桌子顺时针移动每个人 会读出他们的号码。目标是找到那组数字 这形成了一个不断增加的后续序列。所有人都拥有这些 数字将有资格参加幸运抽奖!其中一个软件 开发人员对这一前景感到非常兴奋,并希望最大化 有资格参加抽奖的人数。所以,他 决定编写一个程序来决定谁应该阅读他们的号码 首先是为了最大限度地增加符合条件的人数 幸运抽奖。你能打败他吗? 输入第一行包含t,测试用例数(约15)。然后是t测试案例。每个测试用例包含两个 行:
第一行包含数字N,邀请的访客人数 派对。
第二行包含N个数字a1,a2,...,a分隔 空间,这是写在纸上的数字 顺时针顺序。 输出对于每个测试用例,打印包含单个数字的行,该数字是可以符合条件的最大访客数 参加幸运抽奖。
这是我提出的解决方案
// http://www.codechef.com/problems/D2/
import java.io.*;
import java.util.*;
public class D2
{
public static void main(String [] args)
throws IOException
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int numTestCases = Integer.parseInt(br.readLine());
for(int _t=0; _t<numTestCases; ++_t)
{
int N = Integer.parseInt(br.readLine());
StringTokenizer strtok = new StringTokenizer(br.readLine());
int [] originalArray = new int[N*2];
for(int i=0; i<N; ++i)
{
//this concatenates the array with itself at the time of reading the input itself
originalArray[i] = originalArray[N+i] = Integer.parseInt(strtok.nextToken());
}
//Now we calculate the length of the longest increasing sequence
int maxWinners = new LongestIncreasingSequence(originalArray).lengthOfLongestIncreasingSequence();
System.out.println(maxWinners);
}
}
}
class LongestIncreasingSequence
{
private int [] array;
private int [] longest;
private int subsequence_size;
public LongestIncreasingSequence(int [] A)
{
array = A;
longest = new int[array.length / 2];
longest[0] = array[0];
subsequence_size = 1;
}
public int lengthOfLongestIncreasingSequence()
{
for(int i=1; i<array.length; ++i)
{
if(array[i] < longest[0])
{
longest[0] = array[i];
}
else if(array[i] > longest[subsequence_size - 1])
{
longest[subsequence_size++] = array[i];
}
else
{
//Make the replacement with binary search
longest[getReplacementIndex(array[i])] = array[i];
}
}
return subsequence_size;
}
//Method to find the correct index using binary search
private int getReplacementIndex(int elem)
{
int left, right, mid;
left = 0; right = subsequence_size - 1;
while(right - left > 1)
{
mid = 1 + (right - left) / 2;
if(array[mid] >= elem)
{
if(mid != right) right = mid;
else --right;
}
else
{
left = mid;
}
}
return right;
}
}
复杂度为O(n(log(n))
我通过将数组与自身连接来找到最长的序列。
然而,这并没有超出时间要求,有人可以帮助我加快这种实施。
答案 0 :(得分:1)
我不会进行N
轮换,而是一次性确定最长(循环)运行。这肯定是可行的,你只需要在阵列的末尾小心扭曲。