poj1040 Transportation(DFS)
题目链接
http://poj.org/problem?id=1040
题意
城市A,B之间有m+1个火车站,第一站A站的编号为0,最后一站B站的编号为m,火车最多可以乘坐n人。火车票的票价为票上终点站的编号减去起点站的编号。输入火车票订单的数目orderNums,接着输入orderNums个订单,每个订单由3个数字s,e,p组成,分别表示订单的起点站,终点站,该订单的人数,必须全部接受订单上的乘客或者全部不接受,求铁路公司最多可以赚多少钱。
思路
对于一个订单来说,有两种情况:接受和不接受。我们只需将所有可能的情况枚举出来,然后求在每一种情况下,铁路公司所赚的钱的最大值即可,这种枚举很适合使用dfs来解决。为了简化求解,我们要保证乘客是按火车站的编号顺序来上车,所以要将订单按订单起点的编号从低到高排序,若起点相同,则按终点编号从低到高排序。
代码
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
using namespace std; struct Order
{
int s; //起点
int e; //终点
int p; //人数 Order(int s, int e, int p):s(s), e(e), p(p){}
}; bool cmp(Order o1, Order o2) //将订单排序
{
if(o1.s==o2.s)
return o1.e<o2.e;
return o1.s<o2.s;
} const int N = ;
vector<Order> orders;
int n, m, orderNums;
int down[N]; //down[i]表示第i站下车的人数
int ans; /*
* p : 当前车上的人数
* cur : 当前处理第cur个订单
* sum : 当前赚的钱数
*/
void dfs(int p, int cur, int sum)
{
if(cur==orderNums)
{
ans = max(ans, sum);
return;
} if(cur>) //减去上一个订单的下车人数
{
for(int i=orders[cur-].s+; i<=orders[cur].s; i++)
p-=down[i]; //减去下车的人数
}
if(p+orders[cur].p <= n)
{
down[orders[cur].e] += orders[cur].p;
dfs(p+orders[cur].p, cur+, sum + (orders[cur].e-orders[cur].s)*orders[cur].p);
down[orders[cur].e] -= orders[cur].p; //注意恢复现场,便于回溯
}
dfs(p, cur+, sum);
} int main()
{
//freopen("poj1040.txt", "r", stdin);
while(cin>>n>>m>>orderNums && n)
{
ans = -;
orders.clear();
memset(down, , sizeof(down));
for(int i=; i<orderNums; i++)
{
int s, e, p;
cin>>s>>e>>p;
orders.push_back(Order(s, e, p));
} sort(orders.begin(), orders.end(), cmp);
dfs(, , );
cout<<ans<<endl;
}
return ;
}
一点思考
除了上面代码中的dfs写法,还可以换一种dfs写法,思路是在循环遍历订单时进行dfs,我感觉这种方法比上一种dfs方法要容易想一点,但实现起来比上一种要麻烦一些。代码和上面的代码基本一样,只是dfs函数有所不同。代码如下:
#define _CRT_SECURE_NO_WARNINGS
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
using namespace std; struct Order
{
int s; //起点
int e; //终点
int p; //人数 Order(int s, int e, int p) :s(s), e(e), p(p) {}
}; bool cmp(Order o1, Order o2) //将订单排序
{
if (o1.s == o2.s)
return o1.e<o2.e;
return o1.s<o2.s;
} const int N = ;
vector<Order> orders;
int n, m, orderNums;
int down[N]; //down[i]表示第i站下车的人数
int ans; /*
* p : 当前车上的人数
* pre : 当前处理订单的上一个接受订单
* cur : 当前处理第cur个订单
* sum : 当前赚的钱数
*/
void dfs(int p, int pre, int cur, int sum)
{
if (cur> && cur<orderNums) //减去上一个订单的下车人数
{
for (int i = orders[pre].s + ; i <= orders[cur].s; i++)
p -= down[i]; //减去下车的人数
}
for (int i = cur; i<orderNums; i++)
{
bool flag = false;
for (int j = orders[cur].s + ; j <= orders[i].s; j++) //测试是否能接受订单i
{
p -= down[j]; //减去下车的人数 (位置1)
flag = true;
}
if (p + orders[i].p <= n)
{
pre = i;
down[orders[i].e] += orders[i].p;
dfs(p + orders[i].p, pre, i + , sum + (orders[i].e - orders[i].s)*orders[i].p);
down[orders[i].e] -= orders[i].p; //注意恢复现场,便于回溯
}
if (flag) //只有在位置1减了的情况下再加回来
{
for (int j = orders[cur].s + ; j <= orders[i].s; j++)
p += down[j]; //加上位置1减去的人数,恢复现场,便于回溯
}
}
ans = max(ans, sum);
} int main()
{
//freopen("poj1040.txt", "r", stdin);
while (cin >> n >> m >> orderNums && n)
{
ans = -;
orders.clear();
memset(down, , sizeof(down));
for (int i = ; i<orderNums; i++)
{
int s, e, p;
cin >> s >> e >> p;
orders.push_back(Order(s, e, p));
} sort(orders.begin(), orders.end(), cmp);
dfs(, , , );
cout << ans << endl;
}
return ;
}
这份代码提交后内存占用与第一份代码相同,时间上稍微慢了一点点。
poj1040 Transportation(DFS)的更多相关文章
- LeetCode Subsets II (DFS)
题意: 给一个集合,有n个可能相同的元素,求出所有的子集(包括空集,但是不能重复). 思路: 看这个就差不多了.LEETCODE SUBSETS (DFS) class Solution { publ ...
- LeetCode Subsets (DFS)
题意: 给一个集合,有n个互不相同的元素,求出所有的子集(包括空集,但是不能重复). 思路: DFS方法:由于集合中的元素是不可能出现相同的,所以不用解决相同的元素而导致重复统计. class Sol ...
- HDU 2553 N皇后问题(dfs)
N皇后问题 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Description 在 ...
- 深搜(DFS)广搜(BFS)详解
图的深搜与广搜 一.介绍: p { margin-bottom: 0.25cm; direction: ltr; line-height: 120%; text-align: justify; orp ...
- 【算法导论】图的深度优先搜索遍历(DFS)
关于图的存储在上一篇文章中已经讲述,在这里不在赘述.下面我们介绍图的深度优先搜索遍历(DFS). 深度优先搜索遍历实在访问了顶点vi后,访问vi的一个邻接点vj:访问vj之后,又访问vj的一个邻接点, ...
- 深度优先搜索(DFS)与广度优先搜索(BFS)的Java实现
1.基础部分 在图中实现最基本的操作之一就是搜索从一个指定顶点可以到达哪些顶点,比如从武汉出发的高铁可以到达哪些城市,一些城市可以直达,一些城市不能直达.现在有一份全国高铁模拟图,要从某个城市(顶点) ...
- 深度优先搜索(DFS)和广度优先搜索(BFS)
深度优先搜索(DFS) 广度优先搜索(BFS) 1.介绍 广度优先搜索(BFS)是图的另一种遍历方式,与DFS相对,是以广度优先进行搜索.简言之就是先访问图的顶点,然后广度优先访问其邻接点,然后再依次 ...
- 图的 储存 深度优先(DFS)广度优先(BFS)遍历
图遍历的概念: 从图中某顶点出发访遍图中每个顶点,且每个顶点仅访问一次,此过程称为图的遍历(Traversing Graph).图的遍历算法是求解图的连通性问题.拓扑排序和求关键路径等算法的基础.图的 ...
- 搜索——深度优先搜索(DFS)
设想我们现在身处一个巨大的迷宫中,我们只能自己想办法走出去,下面是一种看上去很盲目但实际上会很有效的方法. 以当前所在位置为起点,沿着一条路向前走,当碰到岔道口时,选择其中一个岔路前进.如果选择的这个 ...
随机推荐
- AI技术说:人工智能相关概念与发展简史
作为近几年的一大热词,人工智能一直是科技圈不可忽视的一大风口.随着智能硬件的迭代,智能家居产品逐步走进千家万户,语音识别.图像识别等AI相关技术也经历了阶梯式发展.如何看待人工智能的本质?人工智能的飞 ...
- c语言时间计算
C语言使用time_t结构体表示时间戳,它本质上是个long类型. 我们可以使用如下函数获取当前时间的时间戳: time_t time(time_t* timer) 函数功能:得到从标准计时点(一般是 ...
- JS函数大全 莫名其妙找到的
1 .document.write(""); 输出语句 2 .JS中的注释为// 3 .传统的HTML文档顺序是:document->html->(head,body) ...
- spring boot 2.0.3+spring cloud (Finchley)8、微服务监控Spring Boot Admin
参考:Spring Boot Admin 2.0 上手 Spring Boot Admin 用于管理和监控一个或多个Spring Boot程序,在 Spring Boot Actuator 的基础上提 ...
- 【C++自我精讲】基础系列六 PIMPL模式
[C++自我精讲]基础系列六 PIMPL模式 0 前言 很实用的一种基础模式. 1 PIMPL解释 PIMPL(Private Implementation 或 Pointer to Implemen ...
- 全面了解 Nginx 主要应用场景
前言 本文只针对Nginx在不加载第三方模块的情况能处理哪些事情,由于第三方模块太多所以也介绍不完,当然本文本身也可能介绍的不完整,毕竟只是我个人使用过和了解到过得.所以还请见谅,同时欢迎留言交流 N ...
- 关于boost 的smart_ptr 的使用问题
boost 的smart_ptr 库中含有好几种智能指针,大家用的最多的应该是shared_ptr ,为啥呢?好用,不用管他啥时候会自动删除等等,而且拷贝和复制都很到位, 但实际上,这个库也有问题,连 ...
- java并发-同步容器类
java平台类库包含了丰富的并发基础构建模块,如线程安全的容器类以及各种用于协调多个相互协作的线程控制流的同步工具类. 同步容器类 同步容器类包括Vector和Hashtable,是早期JDK的一部分 ...
- 用js实现登录的简单验证
实现过程示意图 代码 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> &l ...
- 苹果容器超出内容overflow滑动卡顿问题
-webkit-overflow-scrolling:touch; 就这么一段代码,加载需要滚动的容器css样式中.因为苹果的硬件加速产生的后果....