博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
项目安排(离散化+DP)
阅读量:6404 次
发布时间:2019-06-23

本文共 2597 字,大约阅读时间需要 8 分钟。

题目来源:
题目描述:

小明每天都在开源社区上做项目,假设每天他都有很多项目可以选,其中每个项目都有一个开始时间和截止时间,假设做完每个项目后,拿到报酬都是不同的。由于小明马上就要硕士毕业了,面临着买房、买车、给女友买各种包包的鸭梨,但是他的钱包却空空如也,他需要足够的money来充实钱包。万能的网友麻烦你来帮帮小明,如何在最短时间内安排自己手中的项目才能保证赚钱最多(注意:做项目的时候,项目不能并行,即两个项目之间不能有时间重叠,但是一个项目刚结束,就可以立即做另一个项目,即项目起止时间点可以重叠)。

输入:

输入可能包含多个测试样例。

对于每个测试案例,输入的第一行是一个整数n(1<=n<=10000):代表小明手中的项目个数。
接下来共有n行,每行有3个整数st、ed、val,分别表示项目的开始、截至时间和项目的报酬,相邻两数之间用空格隔开。
st、ed、value取值均在32位有符号整数(int)的范围内,输入数据保证所有数据的value总和也在int范围内。

输出:

对应每个测试案例,输出小明可以获得的最大报酬。

样例输入:
31 3 64 8 92 5 1641 14 105 20 1515 20 818 22 12
样例输出:
1622 思路: 这题初看和01背包问题类似,不同的是这里的开始和截止时间没有明确的上限,所以直接用01背包问题来做肯定是有问题的。这道题给出的上限就是项目的个数最大为10000,我们可以从这个分析,表示时间的状态最多有20000种。所以我们必须对每个项目的开始和截止时间进行离散化到0~20000之间,这样就把问题转化到01背包了。 定义dp[x],表示截止到时间x,小明可以获得的最大报酬。状态转移方程为:   dp[x] = max{dp[x - 1], dp[l]} (l为项目的截止时间为x的开始时间) 对于离散化,可以对项目中出现的开始和截止时间存入set容器进行排序,排序后的各时间在容器中的下标就是它们的离散化值,用这些离散化值来更高对于的项目开始和截止时间就完成了对时间的离散化。 具体代码如下:
1 #include 
2 #include
3 #include
4 using namespace std; 5 6 typedef struct _task_t 7 { 8 int st, sd, value; 9 }task_t;10 11 set
index_map; //用于下标的离散化12 map
index_map_map; //存放离散化的结果13 task_t task_data[10005]; //存放输入数据14 multimap
task_map; //用于任务的映射15 int dp[20005]; //用于dp16 int n; //任务的个数17 int max_proj; //任务的最大时间18 19 #define max(a, b) (a >= b ? a : b)20 int main(void)21 {22 int i;23 pair
::iterator, multimap
::iterator> pos;24 task_t *temp;25 26 // freopen("in.txt", "r", stdin);27 while (cin >> n)28 {29 index_map.clear();30 index_map_map.clear();31 task_map.clear();32 for (i = 1; i <= n; i ++)33 {34 cin >> task_data[i].st >> task_data[i].sd >> task_data[i].value;35 index_map.insert(task_data[i].st);36 index_map.insert(task_data[i].sd);37 }38 i = 0;39 set
::iterator iterator_index = index_map.begin();40 for (; iterator_index != index_map.end(); iterator_index++)41 index_map_map.insert(map
::value_type(*iterator_index, i++));42 max_proj = i;43 for (i = 1; i <= n; i ++)44 {45 task_data[i].st = index_map_map[task_data[i].st];46 task_data[i].sd = index_map_map[task_data[i].sd];47 task_map.insert(multimap
::value_type(task_data[i].sd, &task_data[i]));48 }49 dp[0] = 0;50 for (i = 1; i < max_proj; i ++)51 {52 pos = task_map.equal_range(i);53 dp[i] = dp[i - 1];54 for (; pos.first != pos.second; pos.first++)55 {56 temp = (pos.first)->second;57 dp[i] = max(dp[i], dp[temp->st] + temp->value);58 }59 }60 cout << dp[max_proj - 1] << endl;61 }62 return 0;63 }
View Code
总结:第一次在A题的时候用C++的STL库,表示很强大!!!!

转载地址:http://isjea.baihongyu.com/

你可能感兴趣的文章
[C#]系列文章——关于C#,你应该知道的2000件事情(001)
查看>>
Java发送邮件
查看>>
我的友情链接
查看>>
openstack介绍和初探索
查看>>
我的友情链接
查看>>
perl fork
查看>>
怎么样做Troubleshooting(Root Cause)
查看>>
【华为技术】DHCP配置
查看>>
天地图应用开发许可申请说明!!!尽快修改天地图数据接口
查看>>
linux 生成hash密码的问题
查看>>
MyBatis入门示例
查看>>
解决谷歌被封 打不开
查看>>
nginx + uwsgi 部署
查看>>
Why Blog
查看>>
阅读源码时候的技巧
查看>>
ios push界面怎么拿到push前的界面和push后的界面
查看>>
恢复被误删除的oracle数据文件(一)
查看>>
【oracle】系统权限、对象权限、角色
查看>>
Linux 系统启动流程详解
查看>>
Nginx_PHP配置文件结构设计
查看>>