题目
思路
航线没有交叉等价于左边数列升序情况下右边数列也是升序,因此问题转化为求左边数列升序的情况下右边数列最大上升子列长度,用动态规划解,dp[i]表示以a[i]为结尾的最大上升子列长度
最少去掉的航线数 = 总航线数 - 最大上升子列长度
代码
// 其实就是求左边数列有序的情况下右边数列最大上升子列长度,用动态规划解
// 最少去掉的行线数 = 总航线数 - 最大上升子列长度
#include<cstdio>
#include<algorithm>
const int NMAX = 105;
int n;
int dp[NMAX] = {}; // dp[i]: 以pair[i].y为结尾的最大上升子列长度
struct Pair {
int x, y;
bool operator< (const Pair & b)
{
return x < b.x;
}
}pair[NMAX];
int main()
{
#ifndef ONLINE_JUDGE
freopen("thuSE15_03.txt", "r", stdin);
#endif
int i = 0, j = 0, maxv = 0, ans = 0;
scanf("%d", &n);
for (i=0; i<n; i++)
{
scanf("%d%d", &(pair[i].x), &(pair[i].y));
}
std::sort(pair, pair+n);
// 最大下降子列
dp[0] = 1;
for (i=1; i<n; i++)
{
maxv = 0;
for (j=0; j<i; j++)
{
if (pair[j].y < pair[i].y)
{
maxv = maxv>dp[j]? maxv:dp[j];
}
}
dp[i] = maxv + 1;
ans = ans > dp[i] ? ans : dp[i];
}
printf("%d", n - ans);
return 0;
}