思路
这道题看上去就让人头大,但是仔细分析下。题目要求不能有交叉,例如
poor1
对应
rich4
,那么
poor2
对应
rich5
及以后才算满足条件,
poor3
就要对应
poor2
对应的
rich
的后面……
其实就是将一列作为下标,在另一列里边找最长上升子序列的问题。
PS:二分写起来太难受了,各种边界,头都大了。
代码
#include <cstdio>
using namespace std;
int num[500100];
int dp[500100];
int find(int l, int r, int value)
{
if(l==r) return l;
int mid = (l+r)/2;
if(value>dp[mid]) return find(mid+1, r, value);
else return find(l, mid, value);
}
int main()
{
int n, t=1;
while(scanf("%d", &n)==1)
{
int index, data;
for(int i=1; i<=n; i++)
{
scanf("%d%d", &index, &data);
num[index] = data;
}
int cur = 0;
dp[0] = 0;
for(int i=1; i<=n; i++)
{
if(num[i]>dp[cur])
{
dp[++cur] = num[i];
}
else
{
index = find(1, cur, num[i]);
dp[index] = num[i];
}
}
printf("Case %d:\n", t++);
if(cur==1) printf("My king, at most 1 road can be built.\n\n");
else printf("My king, at most %d roads can be built.\n\n", cur);
}
return 0;
}