/*膜拜一下大神的二分是如何想出来的*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define maxn 0x3f3f3f3f
using namespace std;
const int maxx = 5e+5;
int num[maxx];
int dp[maxx];
int t, n1, n2;
int main()
{
int k = 1;
while(scanf("%d", &t) != EOF){
for(int i = 0; i < t; i++){
scanf("%d%d", &n1, &n2);
num[n1] = n2;
}
int len = 1, low = 1, up, mid = 1;
dp[1] = num[1];
for(int i = 2; i <= t; i++){
low = 1;//注意这里
up = len;//最大指针永远等于序列长度
//-------------------------------------------
while(low <= up){//这里操作对指针的移动需要重点理解很强
mid = (low + up)/2;
if(dp[mid] < num[i]) low = mid + 1;
else up = mid - 1;
}
dp[low] = num[i];//这里是考虑到最长序列与底指针有关更新时候应该注意非常重要
if(low > len) len += 1;
}
//-------------------------------------------以上二分部分非常强膜拜某位大神
printf("Case %d:\n",k);
if(len==1) printf("My king, at most 1 road can be built.");
else printf("My king, at most %d roads can be built.",len);
cout << endl << endl;//注意输出格式
k++;
}
return 0;
}
hdu1025最长上升序列 动态规划 + 二分
最新推荐文章于 2022-05-29 08:47:00 发布