UVA-10020-贪心

Posted shuiyonglewodezzzzz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA-10020-贪心相关的知识,希望对你有一定的参考价值。

  题意:给你一些数轴上的线段,要求寻找出某些线段能够完全覆盖[0,M],并且取的线段数目最小.

解题思路:

 贪心思路,

1.每个线段都有一个L和R,代表它的起点和终点,对于所有R <= 0 ,  L>=R的线段全不要,不符合题意.

2.对于每个线段,根据L进行排序,如果L相同,长度长的排前面.

那么选取的时候只要从原点0开始,每次选取最长的线段即可.

附上一组用例.

3
 
1
-1 0
-5 -3
2 5
0 0

1
-1 0
0 1
0 0 
 

17
0 4
0 1
1 5
4 10
10 13
13 17
5 17
0 0

 

#include <string>
#include<iostream>
#include<map>
#include<memory.h>
#include<vector>
#include<algorithm>
#include<queue>
#include<vector>
#include<stack>
#include<math.h>
#include<iomanip>


namespace cc
{
	using std::cout;
	using std::endl;
	using std::cin;
	using std::map;
	using std::vector;
	using std::string;
	using std::sort;
	using std::priority_queue;
	using std::greater;
	using std::vector;
	using std::swap;
	using std::stack;

	class Point
	{

	public: int l, r, len;
			Point() {};
			Point(int x, int y) :l(x), r(y) {
				if (l < 0)
					this->len = r;
				else
					this->len = r - l; 
			
			};

			int operator < (Point& p)
			{
				int l1 = p.l;
				int l2 = this->l;
				if (l1 < 0)
					l1 = 0;
				if (l2 < 0)
					l2 = 0;
				if (l1 < l2)
					return 0;
				if (l1 == l2)
					return p.len < this->len;
				return 1;
			}

	};

	constexpr int N = 100000;

	int M;
	int ok;
	int ans = 0;
	Point result[N + 1];
	Point input[N + 1];
	int n;

	void init()
	{
		ok = M = ans =n = 0;
	}

	void dump()
	{
		for (int i = 0;i < n;i++)
		{
			cout << input[i].l << " " << input[i].r << endl;
		}
	}

	void search(int curR, int curIndex)
	{
		int curMax = 0;
		int okIndex = -1;
		int endIndex = -1;
		for (int i = curIndex;i < n;i++)
		{
			if ((input[i].l <= curR && input[i].r > curR))
			{
				if (input[i].r > curMax)
				{
					curMax = input[i].r;
					okIndex = i;
					continue;
				}
			}
			if (input[i].l > curR)
			{
				endIndex = i;
				break;
			}
		}
		if (okIndex != -1)
		{
			result[ans++] = input[okIndex];
			if (input[okIndex].r >= M)
			{
				ok = 1;
				return;
			}
			if (endIndex == -1)
				return;
			search(curMax,endIndex);
		}
	}

	void solve()
	{
		int cases;
		cin >> cases;
		int t = 0;
		while (cases--)
		{
			if (t != 0)
				cout << endl;
			t++;
			int l, r;
			init();
			cin >> M;
			while (cin >> l && cin >> r && (l || r))
			{
				if (r <= 0||l >= r)
					continue;
				Point p(l, r);
				input[n++] = p;
			}
			sort(input, input + n);
			//dump();
			search(0,0);
			if (ok)
			{
				cout << ans << endl;
				for (int i = 0;i < ans;i++)
					cout << result[i].l << " " << result[i].r << endl;

			}
			else
			{
				cout << 0 << endl;
			}

		}

	}

};


int main()
{

#ifndef ONLINE_JUDGE
	freopen("d://1.text", "r", stdin);
#endif // !ONLINE_JUDGE
	cc::solve();

	return 0;
}

  

以上是关于UVA-10020-贪心的主要内容,如果未能解决你的问题,请参考以下文章

贪心算法:划分字母区间

763. 划分字母区间-贪心算法

贪心热门问题8:划分字母区间

Contig|scaffold|N50|L50|NG50|贪心算法|de bruiji graph|

CodeForces 1005D Polycarp and Div 3(思维贪心dp)

贪心算法----区间覆盖问题(POJ2376)