HDU 1025 Constructing Roads In JGShining's Kingdom
阿新 • • 發佈:2020-10-27
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> #definemem(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 #defineN 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; }