题目来源:网易有道2013年校园招聘面试二面试题
题目描述:

小明每天都在开源社区上做项目,假设每天他都有很多项目可以选,其中每个项目都有一个开始时间和截止时间,假设做完每个项目后,拿到报酬都是不同的。由于小明马上就要硕士毕业了,面临着买房、买车、给女友买各种包包的鸭梨,但是他的钱包却空空如也,他需要足够的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 思路:
这题初看和01背包问题类似,不同的是这里的开始和截止时间没有明确的上限,所以直接用01背包问题来做肯定是有问题的。这道题给出的上限就是项目的个数最大为10000,我们可以从这个分析,表示时间的状态最多有20000种。所以我们必须对每个项目的开始和截止时间进行离散化到0~20000之间,这样就把问题转化到01背包了。
定义dp[x],表示截止到时间x,小明可以获得的最大报酬。状态转移方程为:
  dp[x] = max{dp[x - 1], dp[l]} (l为项目的截止时间为x的开始时间)
对于离散化,可以对项目中出现的开始和截止时间存入set容器进行排序,排序后的各时间在容器中的下标就是它们的离散化值,用这些离散化值来更高对于的项目开始和截止时间就完成了对时间的离散化。
具体代码如下:
 #include <iostream>
#include <set>
#include <map>
using namespace std; typedef struct _task_t
{
int st, sd, value;
}task_t; set<int> index_map; //用于下标的离散化
map<int, int> index_map_map; //存放离散化的结果
task_t task_data[]; //存放输入数据
multimap<int, task_t *> task_map; //用于任务的映射
int dp[]; //用于dp
int n; //任务的个数
int max_proj; //任务的最大时间 #define max(a, b) (a >= b ? a : b)
int main(void)
{
int i;
pair<multimap<int, task_t *>::iterator, multimap<int, task_t *>::iterator> pos;
task_t *temp; // freopen("in.txt", "r", stdin);
while (cin >> n)
{
index_map.clear();
index_map_map.clear();
task_map.clear();
for (i = ; i <= n; i ++)
{
cin >> task_data[i].st >> task_data[i].sd >> task_data[i].value;
index_map.insert(task_data[i].st);
index_map.insert(task_data[i].sd);
}
i = ;
set<int>::iterator iterator_index = index_map.begin();
for (; iterator_index != index_map.end(); iterator_index++)
index_map_map.insert(map<int, int>::value_type(*iterator_index, i++));
max_proj = i;
for (i = ; i <= n; i ++)
{
task_data[i].st = index_map_map[task_data[i].st];
task_data[i].sd = index_map_map[task_data[i].sd];
task_map.insert(multimap<int, task_t *>::value_type(task_data[i].sd, &task_data[i]));
}
dp[] = ;
for (i = ; i < max_proj; i ++)
{
pos = task_map.equal_range(i);
dp[i] = dp[i - ];
for (; pos.first != pos.second; pos.first++)
{
temp = (pos.first)->second;
dp[i] = max(dp[i], dp[temp->st] + temp->value);
}
}
cout << dp[max_proj - ] << endl;
}
return ;
}
总结:第一次在A题的时候用C++的STL库,表示很强大!!!!

项目安排(离散化+DP)的更多相关文章

  1. nyoj720 项目安排 二分+dp

    思路:dp(i)表示前i个项目的最大收益,转移方程很好写dp(i) = max{ dp(k) + val(i) },val(i)表示第i个项目的价值,dp(k)表示前k个的最佳收益,k满足ed(k) ...

  2. 九度OJ 1499 项目安排 -- 动态规划

    题目地址:http://ac.jobdu.com/problem.php?pid=1499 题目描述: 小明每天都在开源社区上做项目,假设每天他都有很多项目可以选,其中每个项目都有一个开始时间和截止时 ...

  3. 九度oj 题目1499:项目安排

    题目描述: 小明每天都在开源社区上做项目,假设每天他都有很多项目可以选,其中每个项目都有一个开始时间和截止时间,假设做完每个项目后,拿到报酬都是不同的.由于小明马上就要硕士毕业了,面临着买房.买车.给 ...

  4. HDU 2836 (离散化DP+区间优化)

    Reference:http://www.cnblogs.com/wuyiqi/archive/2012/03/28/2420916.html 题目链接: http://acm.hdu.edu.cn/ ...

  5. hdu 4833 离散化+dp ****

    先离散化,然后逆着dp,求出每个点能取到的最大利益,然后看有没有钱,有钱就投 想法好复杂 #include <stdio.h> #include <string.h> #inc ...

  6. LightOJ 1085(树状数组+离散化+DP,线段树)

    All Possible Increasing Subsequences Time Limit:3000MS     Memory Limit:65536KB     64bit IO Format: ...

  7. poj 3666 Making the Grade(离散化+dp)

    Description A straight dirt road connects two fields on FJ's farm, but it changes elevation more tha ...

  8. EcustOJ P109跳一跳(离散化+dp)

    题目链接 感觉这道题我看了很多天,胡思乱想啊,一开始觉得记忆化搜索会可能T啊,,可能出题人的数据卡的好就稳T了的感觉..后来想了想,好像离散化一下,记一下位置之后再记忆化搜索就应该稳了吧..(好像直接 ...

  9. 【POJ3666】Making the Grade 离散化+DP

    学到了一个引理:在满足S最小化的条件下,一定存在一种构造序列B的方案,使得序列B中的数值都来自于A中.(数学归纳法+中位数定理得证) 对于状态的表示来说,首先肯定有一个 i ,表示选到了第 i 个数时 ...

随机推荐

  1. IntelliJ IDEA - 热部署插件JRebel 安装使用教程

    IntelliJ IDEA - JRebel 安装使用教程 JRebel 能做什么? JRebel 是一款热部署插件.当你的 Java-web 项目在 tomcat 中 run/debug 的时候 , ...

  2. MongooseHelper

    /** * Created by lbc on 2016/11/16. */var mongoose=require("mongoose");var db=mongoose.con ...

  3. 怎么将java web 项目导入idea 中

    1.将 java web 项目导 入idea 中, 显示 然后进行 Configure 配置. 2. 点击 open module settings. 3. 4. 选择jar包. 5. 6. 配置to ...

  4. 解决overflow:hidden在安卓微信页面没有效果的办法

    在做h5移动端时候,发现overflow: hidden;在安卓微信页面失效问题,经研究和实验,用第三种方法和第四种方法可以解决! 1.完全隐藏 在<boby>里加入scroll=&quo ...

  5. 【转载】用Ionic开发hybrid APP

    使用phonegap开发APP的优劣在此不必细说,快速,简单,跨平台,以及随着iOS,Android本身对webview优化所带来的不错的性能,便是其独有的优势.而且私以为在目前激烈而又变化快速的移动 ...

  6. express-session 保存遇到的问题

    今天在用express4 试着做网站的时候,发现request.session 中一直不能保存新的值,还一直报一个错 express-session deprecated undefined resa ...

  7. JSP页面之间互相传值

    页面一: <s:if test="#list.sourceId==1">                            <a               ...

  8. UIWindow & UIWindowLevel

    转自:http://www.cnblogs.com/smileEvday/archive/2012/03/27/2420362.html 一.UIWindow是一种特殊的UIView,通常在一个程序中 ...

  9. Jquery源码学习(第一天)

    jQuery是面向对象的设计通过window.$ = window.jQuery = $; 向外提供接口,将$挂在window下,外部就可以使用$和jQuery $("#div1" ...

  10. Extjs扩展:封装Plupload

    关于Plupload Plupload是一个web文件上传组件,支持通过HTML5.Silverlight.Flash或者普通的form来上传文件,提供了过滤文件类型.设置上传文件大小.上传进度.针对 ...