题目来源:网易有道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. CentOS随笔 不断添加

    一.设置IP (1)临时IP  ifconfig eth0 192.168.120.16 (2)永久IP  vi /etc/sysconfig/network-scripts/ifcfg-eth0   ...

  2. 文档ID:某某 模板文件不存在,无法解析文档!

    如果是生成栏目列表时出现这样的问题]:   1.可以修改include/arc.listview.class.php这个文件. 2.复制代码     echo "模板文件不存在,无法解析文档 ...

  3. Java的四种引用方式

    一.引用基本概念 从JDK1.2版本开始,把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期.这四种级别由高到低依次为:强引用.软引用.弱引用.虚引用. 1.强引用(StrongRef ...

  4. chrome浏览器js 导出excel

    <table id="table"> <tr> <th>ID</th> <th>姓名</th> <th ...

  5. canvas绘制简易时钟

    时钟绘制的非常简易,但该有的都有了. 效果图如下, <!DOCTYPE html> <html> <head lang="en"> <me ...

  6. jvm的内存分配总结

    最近看了周志明版本的<深入理解Java虚拟机>第一版和第二版,写的很好,收获很多,此处总结一下.   jvm中内存划分:   如上图,一共分为五块,其中: 线程共享区域为: 1.java堆 ...

  7. 完美解决 Linux 下 Sublime Text 中文输入

    首先,我参考了好几篇文章,都是蛮不错的,先列出来: sublime-text-imfix:首先推荐这个方法,最简单,但是在我的系统上有些问题.可用这个的强烈推荐用这个 完美解决 Linux 下 Sub ...

  8. 多种坐标系之间的转换 Proj.NET和DotSpatial

    Proj.NET ( http://projnet.codeplex.com/)是一个.NET下开源的空间参照和投影引擎,遵循OGC相关标准.负责人(Coordinators )是D_Guidi 和S ...

  9. 安卓动态调试七种武器之离别钩 – Hooking(上)

    安卓动态调试七种武器之离别钩 – Hooking(上) 作者:蒸米@阿里聚安全 0x00 序 随着移动安全越来越火,各种调试工具也都层出不穷,但因为环境和需求的不同,并没有工具是万能的.另外工具是死的 ...

  10. node基本理念(事件、多线程、进程)

    关于node的几点理解: 1.所谓的node单线程,是指node的event loop,也就是我们的业务脚本是跑在一个单线程中的,可以理解为主线程: 2.若存在IO操作,例如文件.网络,是单独在线程里 ...