题目描述:
小明每天都在开源社区上做项目,假设每天他都有很多项目可以选,其中每个项目都有一个开始时间和截止时间,假设做完每个项目后,拿到报酬都是不同的。由于小明马上就要硕士毕业了,面临着买房、买车、给女友买各种包包的鸭梨,但是他的钱包却空空如也,他需要足够的money来充实钱包。万能的网友麻烦你来帮帮小明,如何在最短时间内安排自己手中的项目才能保证赚钱最多(注意:做项目的时候,项目不能并行,即两个项目之间不能有时间重叠,但是一个项目刚结束,就可以立即做另一个项目,即项目起止时间点可以重叠)。
输入:
输入可能包含多个测试样例。
对于每个测试案例,输入的第一行是一个整数n(1<=n<=10000):代表小明手中的项目个数。
接下来共有n行,每行有3个整数st、ed、val,分别表示项目的开始、截至时间和项目的报酬,相邻两数之间用空格隔开。
st、ed、value取值均在32位有符号整数(int)的范围内,输入数据保证所有数据的value总和也在int范围内。
输出:
对应每个测试案例,输出小明可以获得的最大报酬。
样例输入:
3
1 3 6
4 8 9
2 5 16
4
1 14 10
5 20 15
15 20 8
18 22 12样例输出:
16
22算法分析
本题采用回溯法,假定安排了第k个项目后,下一个项目的开始时间肯定在k个项目时间的结束之后。
数据结构
Project
Id
int
代表项目名
Order
int
代表按照项目的开始时间排序后,该项目的序号,从0开始
btime
int
项目起始时间
etime
int
项目结束时间
pf
int
项目收益
在回溯过程中需要查找某个项目的next项目和adjacent项目,为了加快计算速度,所以提前对项目按照开始时间进行排序。
Next项目指某个项目做完后可以接着做的项目
Adjacent项目是指比某个项目开始时间相同或晚一些的项目
现在来讲述具体算法流程
void manageP(int curOrder,int curpf,const std::vector
pv为已经排好序的项目列表
假定已经安排了几个项目,最后一个为curOrder(排序序列号), 求得curOrder的Next项目nextOrder
(1)将nextOrder放入计划。
manageP(nextOrder,curpf+pv.at(nextOrder).pf,pv);
在此要判断nextOrder是否存在,也就是计划是否已经满了,是的话就比较当前的获益,如果比allpf大,就更新allpf.
(2)不加入nextOrder,而是加入nextOrder的adjacentOrder
manageP(adjacentOrder,curpf+pv.at(adjacentOrder).pf,pv);
在此也要判断nextOrder是否是最后一个项目,如果是的话就不存在adjacentOrder,计划已经结束,判断当前收益是否大于allpf.
我们还需要考虑另外一种情况,adjacentOrder的开始时间>=nextOrder的结束时间
在这种情况下得到的收益肯定不是最大,因为中间可以插入nextOrder项目
代码
[cpp]
// test1499.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include
#include
#include
struct Project{
int id;
int order;//记录排序后的位置,便于搜寻下一个项目
int btime;
int etime;
int pf;
};
//std::vector
int allpf=0;//盈利
bool lessthan(const Project &a,const Project &b){
return a.btime < b.btime;
}
int getNextP(int curOrder,const std::vector
if(curOrder==-1)
return 0;
std::vector
for(;cit!=pv.end();cit++){
if(cit->btime >= pv.at(curOrder).etime){
return cit->order;
}
}
if(cit==pv.end()){
return -1;
}
}
/*
int getAdjacentP(const Project &cur, const std::vector
if(cur.order == pv.size()-1)
return 0;
else
return cur.order+1;
}
*/
void manageP(int curOrder,int curpf,const std::vector
//加入
int nextOrder;
nextOrder = getNextP(curOrder,pv);
if(nextOrder==-1){
if(curpf>allpf)
allpf = curpf;
return;
}else{
manageP(nextOrder,curpf+pv.at(nextOrder).pf,pv);
}
if(nextOrder == pv.size()-1){ //nextOrder是最后一个项目
if(curpf+pv.at(nextOrder).pf > allpf){
allpf = curpf+pv.at(nextOrder).pf;
return;
}
}else{
int adjacentOrder = nextOrder+1;
if(pv.at(adjacentOrder).btime >= pv.at(nextOrder).etime){ //adjacentOrder开始时间在nextOrder结束时间之后
//得到的利润肯定没有 加上nextOrder的多
return;
}else{
manageP(adjacentOrder,curpf+pv.at(adjacentOrder).pf,pv);
}
}
}
void test1499(int n){
int i = 0;
Project p;
std::vector
while(i++