最长公共子序列的变形, 但是如果直接使用原来的方式做的话, 时间复杂度为O(n^2) 超时, 所以这里要用二分进行优化, 每次都将之前没有用的数据清除掉, 其中使用了贪心的思想
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#define _MAX 99999999
#define LEN 500005
#define MAX(A,B) (A>B?A:B)
using namespace std;
int node[LEN];
int dp[LEN];
int bs(int len, int t) {
int l = 0;
int r = len-1;
int mid = (l+r)/2;
while(l <= r) {
mid = (l+r)/2;
if(dp[mid] < t) {
l = mid+1;
}
else if(dp[mid] > t) {
r = mid-1;
}
else {
return mid;
}
}
return l;
}
int main() {
int n;
int cse = 1;
while(scanf("%d", &n) != EOF) {
int i, j;
int a, b;
int len, pos;
int val, ans;
memset(node, 0, sizeof(node));
for(i = 0; i < n; i++) {
scanf("%d%d", &a, &b);
node[a] = b;
}
len = 1;
dp[0] = _MAX;
for(i = 1; i <= n; i++) {
val = node[i];
if(val > dp[len-1]) {
dp[len++] = val;
}
else {
pos = bs(len, val);
dp[pos] = val;
}
}
printf("Case %d:\n", cse++);
printf("My king, at most %d %s can be built.\n\n", len, len>1?"roads":"road");
}
return 0;
}