-
小明每天都在开源社区上做项目,假设每天他都有很多项目可以选,其中每个项目都有一个开始时间和截止时间,假设做完每个项目后,拿到报酬都是不同的。由于小明马上就要硕士毕业了,面临着买房、买车、给女友买各种包包的鸭梨,但是他的钱包却空空如也,他需要足够的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
九度 http://ac.jobdu.com/problem.php?pid=1499
题目描述:
-
输入:
-
输出:
-
样例输入:
-
样例输出:
算法分析
本题采用回溯法,假定安排了第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<Project>&pv)
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项目
代码
// test1499.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <algorithm>
struct Project{
int id;
int order;//记录排序后的位置,便于搜寻下一个项目
int btime;
int etime;
int pf;
};
//std::vector<Project> userp;
int allpf=0;//盈利
bool lessthan(const Project &a,const Project &b){
return a.btime < b.btime;
}
int getNextP(int curOrder,const std::vector<Project> &pv){//得到和项目cur时间不重叠的下一个项目
if(curOrder==-1)
return 0;
std::vector<Project>::const_iterator cit = pv.begin() + curOrder +1;
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<Project> &pv){//得到开始时间在项目cur开始时间之后或重合的下一个项目
if(cur.order == pv.size()-1)
return 0;
else
return cur.order+1;
}
*/
void manageP(int curOrder,int curpf,const std::vector<Project> &pv){//已经加入了k-1个项目,k-1为cur项目
//加入
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<Project> pv;
while(i++<n){
std::cin>>p.btime>>p.etime>>p.pf;
p.id = i;
p.order = 0;
pv.push_back(p);
}
std::sort(pv.begin(),pv.end(),lessthan);
for(std::vector<Project>::size_type st = 0;st<pv.size();st++){
pv.at(st).order = st;
}
manageP(-1,0,pv);
std::cout<<allpf<<std::endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
int n =0;
while(std::cin>>n){
test1499( n);
}
return 0;
}
id,order成员变量可以去除,新的代码为
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <algorithm>
struct Project{
//int id;
//int order;
int btime;
int etime;
int pf;
};
int allpf=0;
bool lessthan(const Project &a,const Project &b){
return a.btime < b.btime;
}
int getNextP(std::vector<Project>::size_type curOrder,const std::vector<Project> &pv){
if(curOrder==-1)
return 0;
//std::vector<Project>::const_iterator cit = pv.begin() + curOrder +1;
std::vector<Project>::size_type t = curOrder +1;
for(; t<pv.size(); t++){
if(pv[t].btime >= pv[curOrder].etime){
return static_cast<int>(t);
}
}
if(t==pv.size()){
return -1;
}
}
void manageP(std::vector<Project>::size_type curOrder,int curpf,const std::vector<Project> &pv){
int nextOrder;
nextOrder = getNextP(curOrder,pv);
if(nextOrder==-1){
if(curpf>allpf)
allpf = curpf;
return;
}else{
manageP(static_cast<std::vector<Project>::size_type>(nextOrder),curpf+pv.at(nextOrder).pf,pv);
}
if(nextOrder == pv.size()-1){
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){
return;
}else{
manageP(static_cast<std::vector<Project>::size_type>(adjacentOrder),curpf+pv.at(adjacentOrder).pf,pv);
}
}
}
void test1499(int n){
int i = 0;
Project p;
std::vector<Project> pv;
while(i++<n){
std::cin>>p.btime>>p.etime>>p.pf;
//p.id = i;
//p.order = 0;
pv.push_back(p);
}
std::sort(pv.begin(),pv.end(),lessthan);
/*
for(std::vector<Project>::size_type st = 0;st<pv.size();st++){
pv.at(st).order = st;
}
*/
manageP(-1,0,pv);
std::cout<<allpf<<std::endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
int n =0;
while(std::cin>>n){
test1499( n);
}
return 0;
}
资源下载
C++ Primer Fifth Edition 英文彩色带书签 http://download.csdn.net/detail/kingeasternsun/5529053
C++ Primer Plus (6th Edition) 英文原版 彩色带书签http://download.csdn.net/detail/kingeasternsun/5508691