题目来源:http://poj.org/problem?id=1040

题目大意:

  某运输公司要做一个测试。从A城市到B城市的一条运输线路中有若干个站,将所有站包括A和B在内按顺序编号为0到m。该路线上的一趟列车,乘客最大容量为cap。车开出之前,该趟车会收到来自各个车站的车票订单请求。一个请求包括起点站编号,终点站编号和乘客人数。每张车票的价格为起点到终点之间相隔的站数。在不超载的情况下,求一趟列车能获得的最大收益。对于某一个订单请求,要么接受要么拒绝,不能只接受其中的一部分乘客。

输入:每个测试用例一个数据块。每块的第一行有3个整数:cap:(车的容量), m:(终点城市的编号, 最大为7),n:(订单数,最大为22).接下来的n行每行三个数表示一个订单,三个数分别为起点、终点、人数。

输出:没个测试用例单独一行,输出一个整数表示该趟列车能获得的最大收益。


Sample Input

10 3 4
0 2 1
1 3 5
1 2 7
2 3 10
10 5 4
3 5 10
2 4 9
0 2 5
2 5 8
0 0 0

Sample Output

19
34

由于数据量不算太大,直接用搜索就可以解决。搜索前先对所有订单按起点的顺序进行排序。

不加剪枝的dfs代码,耗时391ms:

 //////////////////////////////////////////////////////////////////////////
// POJ1040 Transportation
// Memory: 264K Time: 391MS
// Language: C++ Result: Accepted
////////////////////////////////////////////////////////////////////////// #include <iostream>
#include <algorithm> using namespace std; int n, m, cap; class Order {
public:
int start;
int destination;
int cnt;
}; Order orders[];
int maxE;
//记录每站有多少个乘客
int pasCnt[]; //比较函数,按start升序,destination降序,cnt降序
bool cmp(const Order &a, const Order &b) {
return a.start == b.start
? (a.destination == b.destination ? (b.cnt < a.cnt) : b.destination < a.destination)
: a.start < b.start;
} void dfs(int i, int now) {
if (now > maxE) {
maxE = now;
}
for (int t = i; t < n; ++t) {
if (pasCnt[orders[t].start] + orders[t].cnt > cap) continue;//reject
for (int j = orders[t].start; j < orders[t].destination; ++j)
//get in
pasCnt[j] += orders[t].cnt;
dfs(t + , now + orders[t].cnt * (orders[t].destination - orders[t].start));
for (int j = orders[t].start; j < orders[t].destination; ++j)
pasCnt[j] -= orders[t].cnt;
}
} int main(void) {
while (true) {
cin >> cap >> m >> n;
if (cap == && m == && n == ) break;
for (int i = ; i < n; ++i)
cin >> orders[i].start >> orders[i].destination >> orders[i].cnt;
//按起点顺序将订单排序
sort(orders, orders + n, cmp);
maxE = ;
memset(pasCnt, , sizeof(pasCnt));
dfs(, );
cout << maxE << endl;
}
system("pause");
return ;
}

(不剪枝DFS)

看了别人剪枝的方法,加上之后,时间瞬间降到16ms.

剪枝方法如下:

每一个order添加两个项v和r。v表示该张订单的收益值。r表示如果选择该选项最多还能获得多少收益,这个值只是一个上界而不是上确界。计算方法是,计算排序后该订单和排在该订单之后的所有订单的收益值之和。因为dfs是按订单顺序依次搜索的,所以当当前收益值加上该订单的r值小于等于已搜到的最大收益,则不必再考虑该订单及以后的订单,因为不可能再得到比已知最大收益更大的收益。

 //////////////////////////////////////////////////////////////////////////
// POJ1040 Transportation
// Memory: 236K Time: 16MS
// Language: C++ Result: Accepted
////////////////////////////////////////////////////////////////////////// #include <iostream>
#include <algorithm> using namespace std; int n, m, cap; class Order {
public:
int start;
int destination;
int cnt;
int v; //该订单能获得的收益
int r; //选取该订单之后最多还能获得多少收益
}; Order orders[];
int maxE;
//记录每站有多少个乘客
int pasCnt[]; //比较函数,按start升序,destination降序,cnt降序
bool cmp(const Order &a, const Order &b) {
return a.start == b.start
? (a.destination == b.destination ? (b.cnt < a.cnt) : b.destination < a.destination)
: a.start < b.start;
} void dfs(int i, int now) {
if (now > maxE) {
maxE = now;
}
for (int t = i; t < n; ++t) {
if (orders[t].r + now <= maxE) return;
if (pasCnt[orders[t].start] + orders[t].cnt > cap) continue;//reject
for (int j = orders[t].start; j < orders[t].destination; ++j)
//get in
pasCnt[j] += orders[t].cnt;
dfs(t + , now + orders[t].v);
for (int j = orders[t].start; j < orders[t].destination; ++j)
pasCnt[j] -= orders[t].cnt;
}
} int main(void) {
while (true) {
cin >> cap >> m >> n;
if (cap == && m == && n == ) break;
for (int i = ; i < n; ++i) {
cin >> orders[i].start >> orders[i].destination >> orders[i].cnt;
orders[i].v = orders[i].cnt * (orders[i].destination - orders[i].start);
}
//按起点顺序将订单排序
sort(orders, orders + n, cmp);
for (int i = n - , sum = ; i >= ; --i) {
sum += orders[i].v;
orders[i].r = sum;
}
maxE = ;
memset(pasCnt, , sizeof(pasCnt));
dfs(, );
cout << maxE << endl;
}
return ;
}

(剪枝)

附上测试数据:


Test Input


Test Output

POJ1040 Transportation的更多相关文章

  1. poj1040 Transportation(DFS)

    题目链接 http://poj.org/problem?id=1040 题意 城市A,B之间有m+1个火车站,第一站A站的编号为0,最后一站B站的编号为m,火车最多可以乘坐n人.火车票的票价为票上终点 ...

  2. Transportation poj1040

    Ruratania is just entering capitalism and is establishing new enterprising activities in many fields ...

  3. POJ 1797 Heavy Transportation(最大生成树/最短路变形)

    传送门 Heavy Transportation Time Limit: 3000MS   Memory Limit: 30000K Total Submissions: 31882   Accept ...

  4. 【HDU 4940】Destroy Transportation system(无源无汇带上下界可行流)

    Description Tom is a commander, his task is destroying his enemy’s transportation system. Let’s repr ...

  5. Heavy Transportation(最短路 + dp)

    Heavy Transportation Time Limit:3000MS     Memory Limit:30000KB     64bit IO Format:%I64d & %I64 ...

  6. POJ 1797 Heavy Transportation (Dijkstra变形)

    F - Heavy Transportation Time Limit:3000MS     Memory Limit:30000KB     64bit IO Format:%I64d & ...

  7. poj 1797 Heavy Transportation(最短路径Dijkdtra)

    Heavy Transportation Time Limit: 3000MS   Memory Limit: 30000K Total Submissions: 26968   Accepted: ...

  8. POJ 1797 Heavy Transportation

    题目链接:http://poj.org/problem?id=1797 Heavy Transportation Time Limit: 3000MS   Memory Limit: 30000K T ...

  9. uva301 - Transportation

      Transportation Ruratania is just entering capitalism and is establishing new enterprising activiti ...

随机推荐

  1. 使用pjsip传输已经编码的视频,源码在github

    pjsip功能很强,做sip rtp语音通话库首选.在2.0之后,也支持视频.不过,它的视频功能缺省是从视频设备采集,然后进行编译,再发送出去的.假设,我们已经有了视频源,比如IP摄像机,不需要采集和 ...

  2. Codeforces Round #402 (Div. 2) 题解

    Problem A: 题目大意: 给定两个数列\(a,b\),一次操作可以交换分别\(a,b\)数列中的任意一对数.求最少的交换次数使得任意一个数都在两个序列中出现相同的次数. (\(1 \leq a ...

  3. 洛谷【P2431】正妹吃月饼

    二进制前置技能:https://www.cnblogs.com/AKMer/p/9698694.html 题目传送门:https://www.luogu.org/problemnew/show/P24 ...

  4. docker-ce安装与搭建私有仓库

    https://www.cnblogs.com/sszhou/p/7389144.html 系统环境centos7 ###docker-ce安装###1.卸载老版本,较老版本的Docker被称为doc ...

  5. MYSQL主从复制配置遇到的问题

    在进行配置从服务器时遇到的错误. mysql> change master to master_host='192.168.136.129',master_user='repl',master_ ...

  6. 【转】 Pro Android学习笔记(四三):Fragment(8):再谈Transaction和管理器

    目录(?)[-] Transaction的一些操作 再谈FragmentManager 调用其他fragment的方法 唤起activity 唤起fragment和相互通信 一些其它 Transact ...

  7. JAVA 1.5 并发之 Executor框架 (二)execute VS submit

    http://www.cnblogs.com/rockman12352/p/3788688.html 上一篇对于整体框架讲了很多东西,但是具体在使用时有一些细节并没有说出来 首先是执行任务 execu ...

  8. TS学习之接口

    TypeScript的核心原则之一是对值所具有的结构进行类型检查.接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约. interface testType { name: string; ...

  9. netstat查看网络信息

    Netstat 命令用于显示各种网络相关信息,如网络连接,路由表,接口状态 (Interface Statistics),masquerade 连接,多播成员 (Multicast Membershi ...

  10. 使用mahout fpgrowth算法求关联规则

    使用mahout fpgrowth 首先,这篇文章的内容大部分取自国外一篇博客Finding association rules with Mahout Frequent Pattern Mining ...