题目来源:网易有道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. sublime Text 3 字体

    1,Comic Sans Ms 2,DejaVu Sans Mono 3,microsoft yahei(微软雅黑) 4,Microsoft Yahei UI(微软雅黑增强版) 5,Ubuntu Mo ...

  2. RecyclerView添加Header的正确方式

    原文链接:http://blog.csdn.net/qibin0506/article/details/49716795 看了一下博客目录,已经有好几篇博客是关于RecyclerView的,不过对于这 ...

  3. VS 默认开发环境如何更改

    话不多说,直接上图

  4. 数据库之SQL编程

    定义局部变量 declare @num int 途径一: 途径二: set 和select赋值方式的区别 唯一区别,如果从数据库表中获取数据,只能用 select ) select @name =st ...

  5. FMX保存JPG格式的Stream

    刚刚看以前的笔记,估计这个用的人很少 var surf:TBitmapSurface; astream:TmemoryStream; begin surf:=TbitmapSurface.Create ...

  6. App测试

    (1)App独特测试点: 客户端兼容性测试:系统版本.不同深度定制的rom.屏幕分辨率.中断测试.安装.卸载.升级.对其他程序的干扰等 需要的一些工具: appnium / lr /  jmeter ...

  7. python获取当前时间的用法

    1.先导入库:import datetime 2.获取当前日期和时间:now_time = datetime.datetime.now() 3.格式化成我们想要的日期:strftime() 比如:“2 ...

  8. iOS开发系列--C语言之预处理

    概述 大家都知道一个C程序的运行包括编译和链接两个阶段,其实在编译之前预处理器首先要进行预处理操作,将处理完产生的一个新的源文件进行编译.由于预处理指令是在编译之前就进行了,因此很多时候它要比在程序运 ...

  9. Verlet-js JavaScript 物理引擎

    subprotocol最近在Github上开源了verlet-js.地址为https://github.com/subprotocol/verlet-js.verlet-js是一个集成Verlet的物 ...

  10. ASP.NET MVC 路由(一)

    ASP.NET MVC路由(一) 前言 从这一章开始,我们即将进入MVC的世界,在学习MVC的过程中在网上搜索了一下,资料还是蛮多的,只不过对于我这样的初学者来看还是有点难度,自己就想看到有一篇引导性 ...