题目来源:网易有道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. [LintCode] Best Time to Buy and Sell Stock II 买股票的最佳时间之二

    Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...

  2. 命令行操作svn和git和git

    前几天在写代码的时候电脑突然坏掉,老大交代的任务没完成,非常痛恨自己用svn或者git保存代码,相信很多程序员遇到过,硬盘坏掉,存在硬盘中的代码丢失,无法找回的问题,svn和git可谓程序员界的福音, ...

  3. Excel表格数据导入到SQLServer数据库

    转载:http://blog.csdn.net/lishuangzhe7047/article/details/8797416 步骤: 1,选择要插入的数据库--右键--任务--导入数据 2,点击下一 ...

  4. FastReport.Net 常用功能总汇

    一.常用控件 文本框:输入文字或表达式 表格:设置表格的行列数,输入数字或表达式 子报表:放置子报表后,系统会自动增加一个页面,你可以在此页面上设计需要的报表.系统在打印处理时,先按主报表打印,当碰到 ...

  5. Unity3D 模型导入Error

    在导入3d max模型的时候报错: 3ds Max could not be found.Make sure that 3ds Max is installed and the max file ha ...

  6. SqlServer存储过程模板

    create procedure [spname]([spvariable])asbegin begin transaction begin try  --具体sql过程  commit; end t ...

  7. sessionStorage/localStorage 本地存储

      if(!sessionStorage.getItem('vote2')||sessionStorage.getItem('vote2')==NaN)sessionStorage.setItem(' ...

  8. 代码自定义双色title的按钮

    所图所示,通过代码自定义这样的按钮. .h文件 // // CustomButtom.h // testPlus // // Created by 鹰眼 on 14/10/20. // Copyrig ...

  9. c#语言-高阶函数

    介绍 如果说函数是程序中的基本模块,代码段,那高阶函数就是函数的高阶(级)版本,其基本定义如下: 函数自身接受一个或多个函数作为输入. 函数自身能输出一个函数,即函数生产函数. 满足其中一个条件就可以 ...

  10. SQL Server null知多少?

    null是什么? 不知道.我是说,他的意思就是不知道(unknown). 它和true.false组成谓词的三个逻辑值,代表“未知”.与true和false相比,null最难以令人捉摸,因为它没有明确 ...