2015年清华软院保研机试第3题:航线交叉 (最大上升子列-动态规划)

题目

思路

航线没有交叉等价于左边数列升序情况下右边数列也是升序,因此问题转化为求左边数列升序的情况下右边数列最大上升子列长度,用动态规划解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;
}

猜你喜欢

转载自blog.csdn.net/da_kao_la/article/details/82431646