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)
设想我们现在身处一个巨大的迷宫中,我们只能自己想办法走出去,下面是一种看上去很盲目但实际上会很有效的方法. 以当前所在位置为起点,沿着一条路向前走,当碰到岔道口时,选择其中一个岔路前进.如果选择的这个 ...
随机推荐
- 手脱ACProtect v1.35(有Stolen Code)
1.载入PEID ACProtect v1.35 -> risco software Inc. & Anticrack Soft 2.载入OD,需要注意的是,异常选项除了[内存访问异常] ...
- 3.6 scikit-learn:Python中的机器学习
sklearn实战-乳腺癌细胞数据挖掘(博主亲自录制视频教程) https://study.163.com/course/introduction.htm?courseId=1005269003&am ...
- windows7中用vitualbox安装OS X 10.11 El Capitan 及 Xcode 7.0--转载
在 Win 7或8 下使用 VirtualBOX 虚拟机安装 OS X 10.11 El Capitan 及 Xcode 7.0 来源:http://bbs.feng.com/read-htm-tid ...
- 【整理】explain、type、extra用法和结果的含义
EXPLAIN列详情 详细解读:https://www.cnblogs.com/yycc/p/7338894.html explain显示了mysql如何使用索引来处理select语句以及连接表.可以 ...
- POJ 3335 Rotating Scoreboard 半平面交求核
LINK 题意:给出一个多边形,求是否存在核. 思路:比较裸的题,要注意的是求系数和交点时的x和y坐标不要搞混...判断核的顶点数是否大于1就行了 /** @Date : 2017-07-20 19: ...
- C++ Arithmetic Exception
运算异常错误,比如除零错误,浮点数取余等等.
- 今日文摘:浅谈 HTML5 的游戏化之路
如今商业网站中用于广泛的HTML5无限下拉效果已经越来越受到游戏网站的喜爱.各个品牌为了打造专属自己的游戏特色,纷纷推出了模拟HTML5效果的品牌 站,且都起到了相当好的效果.可是从很多方面来说我们对 ...
- oracle01--单表查询
1. 基本(基础)查询 1.1. 基本查询语法 基本查询是指最基本的select语句. [语法] [知识点]如何使用工具进行查询 在plsql developer中打开查询窗口(执行sql语句): 执 ...
- Codeforces Round #466
A. Points on the line 题意 给定一条直线上\(n\)个点,要求去掉最少的点,使得直线上相距最远的两个点的距离\(\leq d\). 思路 枚举长度为\(d\)的区间. Code ...
- Ubuntu之设置应用开机自启动
前言 前面使用oricle-Linux的时候,设置开机自启动使用的是chkconfig,现在使用ubuntu的时候发现Ubuntu系统没有了RH系统中的 chkconfig命令,因此研究了一下ubun ...