题目链接

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)的更多相关文章

  1. LeetCode Subsets II (DFS)

    题意: 给一个集合,有n个可能相同的元素,求出所有的子集(包括空集,但是不能重复). 思路: 看这个就差不多了.LEETCODE SUBSETS (DFS) class Solution { publ ...

  2. LeetCode Subsets (DFS)

    题意: 给一个集合,有n个互不相同的元素,求出所有的子集(包括空集,但是不能重复). 思路: DFS方法:由于集合中的元素是不可能出现相同的,所以不用解决相同的元素而导致重复统计. class Sol ...

  3. HDU 2553 N皇后问题(dfs)

    N皇后问题 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description 在 ...

  4. 深搜(DFS)广搜(BFS)详解

    图的深搜与广搜 一.介绍: p { margin-bottom: 0.25cm; direction: ltr; line-height: 120%; text-align: justify; orp ...

  5. 【算法导论】图的深度优先搜索遍历(DFS)

    关于图的存储在上一篇文章中已经讲述,在这里不在赘述.下面我们介绍图的深度优先搜索遍历(DFS). 深度优先搜索遍历实在访问了顶点vi后,访问vi的一个邻接点vj:访问vj之后,又访问vj的一个邻接点, ...

  6. 深度优先搜索(DFS)与广度优先搜索(BFS)的Java实现

    1.基础部分 在图中实现最基本的操作之一就是搜索从一个指定顶点可以到达哪些顶点,比如从武汉出发的高铁可以到达哪些城市,一些城市可以直达,一些城市不能直达.现在有一份全国高铁模拟图,要从某个城市(顶点) ...

  7. 深度优先搜索(DFS)和广度优先搜索(BFS)

    深度优先搜索(DFS) 广度优先搜索(BFS) 1.介绍 广度优先搜索(BFS)是图的另一种遍历方式,与DFS相对,是以广度优先进行搜索.简言之就是先访问图的顶点,然后广度优先访问其邻接点,然后再依次 ...

  8. 图的 储存 深度优先(DFS)广度优先(BFS)遍历

    图遍历的概念: 从图中某顶点出发访遍图中每个顶点,且每个顶点仅访问一次,此过程称为图的遍历(Traversing Graph).图的遍历算法是求解图的连通性问题.拓扑排序和求关键路径等算法的基础.图的 ...

  9. 搜索——深度优先搜索(DFS)

    设想我们现在身处一个巨大的迷宫中,我们只能自己想办法走出去,下面是一种看上去很盲目但实际上会很有效的方法. 以当前所在位置为起点,沿着一条路向前走,当碰到岔道口时,选择其中一个岔路前进.如果选择的这个 ...

随机推荐

  1. lightoj 1148 Mad Counting(数学水题)

    lightoj 1148 Mad Counting 链接:http://lightoj.com/volume_showproblem.php?problem=1148 题意:民意调查,每一名公民都有盟 ...

  2. apk签名验证机制

    声明: 1.本帖转载自:http://riusksk.blogbus.com/logs/272154406.html,仅供自用,勿喷 2.欢迎交流学习 签名后的APK,在/META-INF目录下会生成 ...

  3. php 三元运算符简洁用法

    <?php header('Content-type:text;charset=utf8'); $a = 'aaaa'; $b = $a ?:'; $c = $a ? $a : '; //这个和 ...

  4. 「Django」rest_framework学习系列-节流控制

    1.节流自定义类: import time from api import models VISIT_RECORD = {} class VisitThrottle(BaseThrottle): #设 ...

  5. Dozer 对象的"搬运工"

    前言:项目中,经常会遇到各层对象之间相互进行值传递的过程,如在数据据持久层有一持久类EntityA,在视图层可能会变为ViewA,通常情况下,这两个类的属性 名称 .类型都是一致的,   在两个对象传 ...

  6. ACM-ICPC2018 沈阳赛区网络预赛-E-The cake is a lie

    You promised your girlfriend a rounded cake with at least SS strawberries. But something goes wrong, ...

  7. HTML入门(一)

    ---恢复内容开始--- HTML 一 .HTML介绍 1. 什么是HTML? 超文本标记语言: 超文本: 比普通文本更强大 标记语言: 使用一组标签对内容进行描述的一门语言,它不是编程语言! 2. ...

  8. 51nod1110 距离之和最小 V3

    基准时间限制:1 秒 空间限制:131072 KB 分值: 40  X轴上有N个点,每个点除了包括一个位置数据X[i],还包括一个权值W[i].该点到其他点的带权距离 = 实际距离 * 权值.求X轴上 ...

  9. iOS网络基础---iOS-Apple苹果官方文档翻译

    CHENYILONG Blog iOS网络基础---iOS-Apple苹果官方文档翻译 iOS网络基础 技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博http: ...

  10. 2017ACM暑期多校联合训练 - Team 8 1008 HDU 6140 Hybrid Crystals (模拟)

    题目链接 Problem Description Kyber crystals, also called the living crystal or simply the kyber, and kno ...