【题目链接】:click here~~
【题意】:河岸两旁有n个村庄,他们之间要互相修路,并且同一边的不互相修,在保证不交叉的情况下,最大限度的路的是多少。
【思路】转化题意后,发现是求LIS,入门题训练
LIS详细分析:LIS问题
代码:
/* * Problem: HDU No.1025 * Running time: 374MS * Complier: G++ * Author: javaherongwei * Create Time: 8:47 2015/9/28 星期一 *LIS(最长递增子序列) */ #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; typedef long long LL; const int N=500000+10; int dp[N]; int B[N],C[N],D[N]; int len; int LIS(int *a,int n);///计算最长递增子序列的长度,计算B数组的元素,arr[]循环完一遍后,B的长度len即为所求 int LISsearch(int *b,int len,int p);///二分查找需要插入的位置 int LIS(int *a,int n) { len=1; B[0]=a[0]; D[0]=1;///表示已i结尾的LIS int pos=0; for(int i=1; i<n; ++i) { if(a[i]>B[len-1])///如果大于B中最大的元素,则直接插入到B数组末尾 { B[len]=a[i]; ++len; } else { pos=LISsearch(B,len,a[i]);///二分查找需要插入的位置 B[pos]=a[i]; } D[i]=len; } return len; } int LISsearch(int *b,int len,int p) { int left=0,right=len-1; int mid; while(left<=right) { mid=(left+right)>>1; if(b[mid]>p) right=mid-1; else if(b[mid]<p) left=mid+1; else return mid; ///找到了该元素,则直接返回 } return left; } inline LL read() { int c=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();} return c*f; } int main() { int t,tot=1; while(~scanf("%d",&t)) { for(int i=0; i<t; ++i) { int a,b; a=read();b=read(); dp[a-1]=b-1; } int ans=LIS(dp,t); printf("Case %d:\n",tot++); if(ans==1) {puts("My king, at most 1 road can be built.");puts("");} else { printf("My king, at most %d roads can be built.\n",ans);puts("");} } return 0; }