您的位置:首页 > 其它

利用贪心的思维对算法剪枝(POJ 2376)

2015-07-05 17:21 295 查看
http://poj.org/problem?id=2376

这是昨天遇到的一道题吧,题目的意思非常简单。一个农民在一些天里需要一些奶牛为他工作。他可以找到n头奶牛,但是,任意的一头奶牛都只有特定的日子里才能进行工作。所以,我们要计算得出他最少需要雇佣多少头奶牛。(如果不能天天都雇佣到奶牛即输出-1).

这题的思路十分简单,首先我们从第一天开始,找到一头工作时间最久的奶牛(设工作到n天),将其转化为规模更小的问题。然后继续寻找符合条件的工作时间最长的奶牛,直到时间结束。但是,这样做,就不得不联系遍历所有奶牛的数据,造成复杂度增大(TLE),所以,如何进行优化呢?首先,我们对奶牛根据其开始工作的时间进行排序。这样当确定工作开始的时间后,我们只需要遍历工作开始时间小于start的时间。这样还不够,我们利用一个数组记录下上一头奶牛工作开始的时间,因为如果有奶牛工作时间早于上一头奶牛且工作时间更长,那么它才是上一段时间的最优解。由此我们就可以完成对这个算法的优化。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
struct cow
{
int a, b;
}data[25005];
int start,endi,n,flag,previ[25005];
bool comp(cow a, cow b)
{
if (a.a < b.a)return true;
else return false;
}
int main()
{
int i,temp1,temp2;
while (scanf_s("%d %d", &n, &endi) != EOF)
{
flag = 0;
int result = 0;
start = 1;
for (i = 1; i <= n; i++)
scanf_s("%d %d", &data[i].a, &data[i].b);
sort(data + 1, data + n + 1, comp);
temp1 = 1; previ[1] = 0;
while (start <= endi)
{
while (data[temp1].a <= start&&temp1 <= n)temp1++;  //temp前驱到遍历条件的上界即temp1<=start
i = temp1-1;
temp2 =start-1;
while(data[i].a >= previ[result + 1]&&i>0)
{
if (data[i].b > temp2)
{
previ[result + 2] = data[i].a;       //记录下奶牛开始工作的时间以剪枝
temp2 = data[i].b;
}
i--;
}
if (temp2 == start-1){ flag = 1; break; }   //没有符合条件的奶牛,即退出
start = temp2 + 1;
result++;
}
if (!flag)cout << result << endl;
else cout << "-1" << endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: