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)
设想我们现在身处一个巨大的迷宫中,我们只能自己想办法走出去,下面是一种看上去很盲目但实际上会很有效的方法. 以当前所在位置为起点,沿着一条路向前走,当碰到岔道口时,选择其中一个岔路前进.如果选择的这个 ...
随机推荐
- switch滑动开关
<!DOCTYPE html> <html> <head > <meta charset="utf-8"> <title> ...
- 驱动学习3.1:获取zynqled的物理地址
自己想要打印EMIO管脚的物理地址,在SDK提供的头文件中加入printf是无法打印的,基于此 我将需要打印地址的几个函数提取出来,放在main函数中,然后在里面加入printf打印这些用户管脚的地址 ...
- 前端PHP入门-016-静态变量
如果我想知道函数被调用了多少次怎么办?在没有学习静态变量的时候,我们没有好的办法来解决. 静态变量的特点是:声明一个静态变量,第二次调用函数的时候,静态变量不会再初始化变量,会在原值的基础上读取执行. ...
- Qt每次运行都是重新编译问题
按理说,Qt使用了makefile技术只会编译刚修改的源文件,但有时会遇到一运行项目就会重新编译的问题,严重浪费了时间. 问题就出在你的系统时间上,系统时间的不准确会影响makefile机制的判断过程 ...
- 解决SpringMVC put,patch,delete请求数据拿不到的问题
解决SpringMVC put,patch,delete请求参数拿不到的问题 废话不多说,核心代码如下: 在web.xml中添加如下代码 <!-- 解决web端不能put,delete等请求的问 ...
- CSS预处理器们
CSS预处理器有很多,最早的是2006年的Less,到后来2010年的SASS,还有现在也很出名的Stylus.不过要使用它们都要使用一些工具,比如Less的话要使用Grunt或者Gulp或者Node ...
- 在ASP.NET中备份和还原数据库
昨天看了<C#项目实录>中的进销存管理系统,和其他书里讲的案例一样,无非也就是数据库增删查改,但是这个进销存系统中有一个备份和还原数据库的功能,蛮有兴趣的,看了一下代码,原来如此, ...
- 关于static关键字
static用于修饰成员(成员变量,成员函数),不能修饰局部变量被修饰的变量和函数是静态的,可被多个对象共享,节省内存可以直接被类名调用++++++++++++++++++++++++++++++++ ...
- 【BZOJ】3992: [SDOI2015]序列统计 NTT+生成函数
[题意]给定一个[0,m-1]范围内的数字集合S,从中选择n个数字(可重复)构成序列.给定x,求序列所有数字乘积%m后为x的序列方案数%1004535809.1<=n<=10^9,3< ...
- input复选框checkbox默认样式纯css修改
修改之前的样式 修改之后的样式 html <input type="checkbox" name="btn" id="btn1"&g ...