uva 10534 - Wavio Sequence

来源:互联网 发布:网络摄像头电源多少伏 编辑:程序博客网 时间:2024/05/17 09:18
import java.math.BigInteger;import java.util.*;public class shopping {    public static void main (String [] args) throws Exception {        Scanner scan = new Scanner(System.in);        while(scan.hasNextInt()){            int num = scan.nextInt();            int arr[] = new int[num];            for(int i=0;i<num;i++){                arr[i] = scan.nextInt();            }            int inc[] = new int[num];            int stack[] = new int[num+1];            int top = 0;            stack[0] = Integer.MIN_VALUE;            for(int i=0;i<num;i++){                int tmp = arr[i];                if(tmp>stack[top]){                    stack[++top] = tmp;                }else{                    int mid = 0, low = 1, high = top;                    while(low<=high){                        mid = (low+high)/2;                        if(stack[mid]==tmp) break;                        else if(stack[mid]>tmp)                            high = mid-1;                       else                            low = mid+1;                                            }                    stack[low] = tmp;                }                inc[i] = top;            }                        int dec[] = new int[num];            stack = new int[num];            stack[0] = Integer.MIN_VALUE;            top = 0;            for(int i=num-1;i>=0;i--){                int tmp = arr[i];                if(tmp>stack[top]){                    stack[++top] = tmp;                }else{                    int mid = 0, low = 1, high = top;                    while(low<=high){                        mid = (low+high)/2;                        if(stack[mid]==tmp) break;                        else if(stack[mid]>tmp){                            high = mid-1;                        }else{                            low = mid+1;                        }                    }                    stack[low] = tmp;                }                dec[i] = top;            }            int max = -1;            for(int i=0;i<num;i++){                if(max<Math.min(inc[i], dec[i]))                    max = Math.min(inc[i], dec[i]);            }            System.out.println(2*max-1);            Dumper.print_1_arr(stack, top+1);        }    }}

最开始呢,当然是闭着眼睛上了N平方的算法。。。然后误以为是scanner效率低,改bufferedReader做,还是无尽的TLE,RE。。。

无奈,上网找报告。然后想起来LIS是还有NlogN的算法。

这个算法以前见过的,算法实在不能算直观。我也很久没碰了,都忘记了。

然后算是回忆一下吧,其实现在都不算彻底掌握了。。。


这个算法用了一个数组保存LIS的最优解。这个最优解不是指长度了。

比如长度都是5,第一个sequence是 1,2,3,4,5 第二个是1,2,3,4,10

那么这个数组存的就是第一个sequence,第一个是最优的sequence, 因为5是比10小的,这样就有为后面提供了更多的选择,

比如下一个数如果是6,就能加进来,这样sequence又变长了


这样对于输入数组array[1...n], 这个数组(叫它stack[1..n]吧)就保存了到第i 个数的最优subsequence

所以呢,下一个数array[i+1]只要比stack[top]大,那么它就能加入,从而sequence长度增长了1

为了确保这个sequence存的是最优子序列,必须不断更新子序列。

后面那个二分搜索就是把更小的值更新进来,这个更新是有可能连top位置的值也更新的。