1. 程式人生 > 實用技巧 >HDU 1025 Constructing Roads In JGShining's Kingdom

HDU 1025 Constructing Roads In JGShining's Kingdom

HDU 1025 Constructing Roads In JGShining's Kingdom

題意:

給你n個富有的城市和n個貧窮的城市

然後給你n個連線(確保是一對一的連線)

然後讓你求最多有多少條線在沒有交叉的情況下同時存在

解題思路:

在一對一情況下,假設我們把一邊的城市按照順序進行排列

那麼每一座城市對應的另一邊的城市的編號就形成了一個序列

而只要求出這個序列的最長上升序列的長度,那麼就是本題的解

求最長子序列O(nlogn)的模板如下:

c[1]=a[1].r;
        int len=1;
        for(int i=2;i<=n;++i)
        {
            
if(a[i].r>c[len]) { c[++len]=a[i].r; } else { int j=lower_bound(c+1,c+len+1,a[i].r)-c; c[j]=a[i].r; } }

其中c為最後的最長子序列的一種情況,len為最長子序列的長度

本題程式碼:

#include <bits/stdc++.h>
#define
mem(a) memset(a,0,sizeof(a)) #define mem1(a) memset(a,-1,sizeof(a)) #define forn(i,n) for(int i=0;i<n;++i) #define for1(i,n) for(int i=1;i<=n;++i) #define IO std::ios::sync_with_stdio(false); std::cin.tie(0) #define ll long long #define LL long long #define inf 0x3f3f3f3f #define INF 0x3f3f3f3f3f3f3f3f #define
N 1000000 using namespace std; const int maxn=5e5+50; //ll gcd(ll a, ll b){return b ? gcd(b, a % b) : a;} //ll lcm(ll a, ll b){return a * b / gcd(a, b);} struct Node { int p,r; }a[maxn]; int b[maxn],c[maxn]; bool cmp(Node a,Node b) { return a.p<b.p; } int main() { int n,k; k=1; while(~scanf("%d",&n)) { for1(i,n) { scanf("%d %d",&a[i].p,&a[i].r); } sort(a+1,a+n+1,cmp); c[1]=a[1].r; int len=1; for(int i=2;i<=n;++i) { if(a[i].r>c[len]) { c[++len]=a[i].r; } else { int j=lower_bound(c+1,c+len+1,a[i].r)-c; c[j]=a[i].r; } } printf("Case %d:\n",k++); if(len==1) printf("My king, at most %d road can be built.\n\n",len); else printf("My king, at most %d roads can be built.\n\n",len); } return 0; }

ps:注意單數和複數的時候輸出語句中的road的單複數形式,賊坑