您的位置:首页 > 其它

vijos P1638 抢救文件

2015-07-17 10:26 267 查看
发现这个题库里面的题目理解起来好费劲。

这个算是一个二维LIS吧。

/*
vojis P1638抢救文件
题意:通道大小为x(长)*y(宽)[应该是数据原因,这个x,y好像并没有什么用,应该是用来判别
                            陷阱是否超出通道,好像数据都没有超出。]
	有n个陷阱,陷阱的d,c分别为陷阱所在的坐标系的位置(把通道看出坐标系,则陷阱位置为(c,d))
	每个陷阱不能出现交叉(简单来说就是要保持上升[二维LIS问题]
解法:sort+LIS (n*longn)
*/
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN=500005;
struct Node
{
	long long int d;
	long long int c;
};
Node a[MAXN];
Node dp[MAXN];
bool cmp(Node a,Node b)
{
	if(a.c==b.c)
	{
		return a.d>b.d;
	}
	else
	{
		return a.c<b.c;
	}
}
int main()
{
	long long int x,y;
	int n;
	cin>>x>>y>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i].c>>a[i].d;
	}
	sort(a+1,a+n+1,cmp);
	int top=0;
	dp[0].c=0,dp[0].d=0;
	for(int i=1;i<=n;i++)
	{
		if((a[i].c>=dp[top].c)&&(a[i].d>=dp[top].d))
		{
			top++;
			dp[top].c=a[i].c;
			dp[top].d=a[i].d;
		}
		else
		{
			int l=1,r=top,mid;
			while(l<=r)
			{
				mid=(l+r)/2;
				if ((a[i].c >= dp[mid].c)&&(a[i].d>=dp[mid].d))
				{
					l = mid + 1;
				}
				else
				{
					r = mid - 1;
				}
			}
			dp[l].c=a[i].c;
			dp[l].d=a[i].d;
		}
	}
	cout<<top<<endl;
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: