hdu1025 最长上升子序列 O(nlogn)优化版

来源:互联网 发布:js多选日期插件 编辑:程序博客网 时间:2024/06/17 12:19

这题坑点挺多。

首先,输入很大,虽然看懂了是最长上升子序列,但第一次用朴素查找,妥妥的超时了。。

学习一下二分查找LIS,可以优化到O(nlogn)。

还有就是英文输出时,一定要注意复数复数!!之前有道题也是用到各种数序的英文输出。不注意的话就会WA。

二分查找LIS,其实就是拿一个数组f[],下标表示长度,存放该长度序列的末尾数。该数组存放的末尾数也一定是递增的。


#include<iostream>#include<algorithm>#define max(a,b) a>b?a:busing namespace std;static int f[500002];static int nd[500002];int n;int main(){int fm,to,maxr,kcase = 1;;while(~scanf("%d",&n)){for(int i = 0;i<n;i++){scanf("%d%d",&fm,&to);nd[fm] = to;}int len = 1;f[1] = nd[1];for(int i = 2;i<=n;i++){int low = 1,high = len,mid;//二分法优化 while(low <= high){int mid = (high + low)/2;if(f[mid]<nd[i]){low = mid+1;}else{high = mid-1;}}//这里是找到了最小的大于nd[i]的数f[low] = nd[i]; //更新 len = low>len?low:len;}//这里复数也挺坑。。 if(len == 1){printf("Case %d:\nMy king, at most 1 road can be built.\n\n",kcase);}else{printf("Case %d:\nMy king, at most %d roads can be built.\n\n",kcase,len);}kcase++;}return 0;}


原创粉丝点击