传送门:POJ 1631
题意:这个题题意不好懂,不过看图就能明白了,就是让你去掉最少的线段,使得所有的线段都不想交。
思路:将线段用点对表示,左端点为一个递增的序列1,2,3....n,右端点是一个1-n的排列,不难发现在这样情况下若要不相交,则左端点比前面大的线段的右端点一定也比前面的线段大,即在右端点的排列中找一个最长的递增子序列,转化为LIS求解。
其实对着样例看也能看出是最长上升子序列的。
代码:
#include<stdio.h>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
int a[50000], dp[50000];
int main()
{
int T, n;
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
for(int i = 0; i < n; i++)
scanf("%d", a + i), dp[i] = inf;
for(int i = 0; i < n; i++)
*lower_bound(dp, dp + n, a[i]) = a[i];
printf("%d\n", lower_bound(dp, dp + n, inf) - dp);
}
}