hdu1025 Constructing Roads In JGShining's Kingdom

来源:互联网 发布:数据库添加数据 编辑:程序博客网 时间:2024/05/22 03:50

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1025

题目大意:不多bb~

题目思路:就是LIS(longgest increasing sequence)的应用。主要提一下最长上升子序列的求法吧。

朴素解法:复杂度o(n^2),对于位置i,满足dp[i]=max(1,dp[j]+1),j<i,a[j]<a[t];dp[i]指以i位置结尾的最长上升子序列。

高级版:复杂度o(nlog(n)),dp+二分查找。引进d[len]数组表示长度为len的上升子序列中的最小末尾元素。则对于a[i],若a[i]>d[len],则d[++len]=a[i],否则,在d[1~len-1]中寻找最大的j,满足d[j]<a[i],然后d[j+1]=a[i]。

感想:感觉做法很玄学(至少目前看来~无奈~),用到贪心的思想可能会帮助理解一些,对于i,j,若dp[i]=dp[j],肯定选择a[]更小的那个,此外已经求得长度为len的情况下,只需更新前面长度满足条件的最长的就好了。另外,不得不提,这题输出有点坑~,还要多打一个空格,又没说,无语。

ac代码:

#include<iostream>#include<algorithm>#define ll long longusing namespace std;const int N=5e5+5;int a[N],b[N];int main(){int n,p=1;while(scanf("%d",&n)!=EOF){int j,len=0,t;for(int i=0;i<n;i++){scanf("%d%d",&j,&t);a[j]=t;}b[0]=0;for(int i=1;i<=n;i++){if(a[i]>b[len]){b[++len]=a[i];}else{int k=lower_bound(b+1,b+len+1,a[i])-b;b[k]=a[i];}}printf("Case %d:\n",p++);if(len==1) printf("My king, at most 1 road can be built.\n\n");else printf("My king, at most %d roads can be built.\n\n",len);}return 0;}


原创粉丝点击