题目地址:HDU-1025
看了题解才知道这是个求最长上升子序列的题,然鹅,动态规划啥的都忘了 QAQ
自己想了想递归,但是WA了,留白,以后再总结
看了网上的题解,绝大部分做最长子序列都是用递推
用一个m[i]数组表示当子序列长度为i时最后一个数
然后从1-n递推,如果a[i]>m[len],则加在后面,否则从1-len中寻找a[i]>=m[p],m[p]=a[i];
如果x>y,则m[x]>m[y]
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int n,a[500005],m[500005];
int findd(int x,int l,int r) { //找到最小的大于等于它的数
int mid;
while(l<=r) {
mid=(l+r)>>1;
if(m[mid]==x)
return mid;
if(m[mid]<x)
l=mid+1;
else
r=mid-1;
}
return l;
}
int main() {
int i,t=1,poor,rich,len;
while(~scanf("%d",&n)) {
for(i=1; i<=n; i++) {
scanf("%d %d",&poor,&rich);
a[poor]=rich;
}
m[0]=a[1];
len=1;
for(i=2;i<=n;i++){
if(a[i]>m[len-1]){
m[len++]=a[i];
}else{
int p=findd(a[i],0,len);
m[p]=a[i];
}
}
printf("Case %d:\n",t++);
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;
}