一往直前!贪心法 区间 poj 2376解题报告

wa了几发的弱鸡来写结题思路了

这是某位dalao的思路

我在上面盖了盖

#include <iostream>
#include <algorithm>
using namespace std;
int N, T;
const int MAX_COWS=25005;
struct Cow
{
	int begin;	// 开始时间
	int end;	// 结束时间
}cow[MAX_COWS];




bool is_greater(const Cow& a, const Cow& b)
{
	return a.begin < b.begin || (a.begin == b.begin && a.end > b.end);
}

int solve()
{
	int used_cows = 0;
	int end = 0;
	int index = 0;
	while(end < T)
	{
		int begin = end + 1;
		// 寻找一头既能从begin干起,又能一直干到最远的牛
		for (int i = index; i < N; ++i)
		{
			if (cow[i].begin <= begin)
			{
				// 能够覆盖起始点
				
					// 将终点延长到最远
					end = max(end, cow[i].end);

			}
			else
			{
				// 不能覆盖起始点,说明上一头牛的终点就是最远点,需要换一头牛了
				index = i;
				break;
			}
		}

		// 没找到这样的牛,这个case失败
		if (begin > end)
		{
			return -1;
		}
		else
		{
			++used_cows;
		}
	}

	return used_cows;
}


int main()
{

	cin >> N >> T;
	for (int i = 0; i < N; ++i)
	{
		cin >> cow[i].begin >> cow[i].end;
	}
	sort(cow, cow + N, is_greater);
	cout << solve() << endl;

    return 0;
}

上面是我的

说几个注意点吧

1

struct Cow
{
	int begin;	// 开始时间
	int end;	// 结束时间
}cow[MAX_COWS];

这是构造Cow型的数组

这个数组里有两个元素 begin end 调用 begin  end 怎么比较呢

一定要注意这段代码

bool is_greater(const Cow& a, const Cow& b)
{
	return a.begin < b.begin || (a.begin == b.begin && a.end > b.end);
}


传数组进行比较的时候穿的是地址!!!

比如

int cmp(const void *a, const void *b)//按start从小到大,end从小到大排序   
{  

微笑

然后思路就是

先去排好序 然后开始只要<上一次的end 依次更新end值奋斗

定义数组别忘了const啊


主要还是中间代码啦。。。。。。、。。。。


一道区间重叠问题。排序+贪心可解。但是题目有个陷阱,容易让人走入思维误区。 
给出2个区间。 
2 5 
6 8 
如果用数轴表示,这个区间应该是不重合的。但是,实际情况是,一头牛清理完2-5号,下一头牛可以从6号开始清理,这很正常嘛。然后讨论区很多人(包括我)一开始都认为是最多到5号开始清的。


#include <iostream>
#include <algorithm>
using namespace std;
int N, T;
 
struct Cow
{
	int begin;	// 开始时间 
	int end;	// 结束时间 
};
 
#define MAX_COWS 25000
Cow cow[MAX_COWS];
 
bool is_greater(const Cow& a, const Cow& b)
{
	return a.begin < b.begin || (a.begin == b.begin && a.end > b.end);
}
 
int solve()
{
	int used_cows = 0;
	int end = 0;
	int index = 0;
	while(end < T)
	{
		int begin = end + 1;
		// 寻找一头既能从begin干起,又能一直干到最远的牛 
		for (int i = index; i < N; ++i)
		{
			if (cow[i].begin <= begin)
			{
				// 能够覆盖起始点 
				if (cow[i].end >= begin)
				{
					// 将终点延长到最远 
					end = max(end, cow[i].end);
				}
			}
			else
			{
				// 不能覆盖起始点,说明上一头牛的终点就是最远点,需要换一头牛了 
				index = i;
				break;
			}
		}
 
		// 没找到这样的牛,这个case失败 
		if (begin > end)
		{
			return -1;
		}
		else
		{
			++used_cows;
		}
	}
 
	return used_cows;
}
 
///SubMain//
int main(int argc, char *argv[])
{
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
#endif
	cin >> N >> T;
	for (int i = 0; i < N; ++i)
	{
		cin >> cow[i].begin >> cow[i].end;
	}
	sort(cow, cow + N, is_greater);
	cout << solve() << endl;
#ifndef ONLINE_JUDGE
    fclose(stdin);
    fclose(stdout);
    system("out.txt");
#endif
    return 0;
}
///End Sub//




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值