小记:这题思考了很久,唉~ 最后还是没摸出LIS来...
思路:求出LIS(最长递增子序列)的长度即可。
不过要注意输出,如果只有一个的话,road 就没有s,否则就是roads
关于LIS的O(nlogn)的算法,请参考:LIS(三大算法)
代码:
#include <iostream> #include <stdio.h> #include <algorithm> #include <queue> #include <stack> #include <vector> #include <string.h> #include <stdlib.h> #include <map> #include <set> using namespace std; #define REP(a,b,c) for(int a = b; a < c; ++a) const int MAX_ = 500010; const int INF = 0x7fffffff; const int N = 500010; struct node{ int id, v; }p[MAX_], q[MAX_]; int d[MAX_]; int B[MAX_]; bool cmp(const node &a, const node &b){ if(a.id < b.id)return true; else return false; } int LIS(int d[], int T){ int *B = new int[T+1]; int l, r, mid, len = 0; B[0] = d[1]; REP(i, 2, T+1){ if(d[i] > B[len]){B[++len] = d[i];continue;} l = 0; r = len; while(l <= r){ mid = l + (r-l)/2; if(B[mid] < d[i])l = mid + 1; else r = mid - 1; } B[l] = d[i]; //if(l > len) len ++; } delete[] B; return len + 1; } int main() { int T, s, t, Ca = 1; while(~scanf("%d",&T)){ REP(i, 0, T){ scanf("%d %d", &s,&t); p[s].v = t; q[t].v = s; p[s].id = s; q[t].id = t; } sort(p+1, p+T+1, cmp); REP(i, 1, T+1){ d[i] = p[i].v; } int cnt; cnt = LIS(d, T); /*REP(i, 1, T+1){ printf("%d %d\n",p[i].id, p[i].v); } printf("\n");*/ sort(q+1, q+T+1, cmp); REP(i, 1, T+1){ d[i] = q[i].v; } int ans; ans = LIS(d, T); if(ans > cnt)cnt= ans; printf("Case %d:\n", Ca++); if(ans == 1) printf("My king, at most %d road can be built.\n\n", cnt); else printf("My king, at most %d roads can be built.\n\n", cnt); } return 0; }