Problem Description

The famous ACM (Advanced Computer Maker) Company has rented a floor of a building whose shape is in the following figure.

The floor has 200 rooms each on the north side and south side along the corridor. Recently the Company made a plan to reform its system. The reform includes moving a lot of tables between rooms. Because the corridor is narrow and all the tables are big, only one table can pass through the corridor. Some plan is needed to make the moving efficient. The manager figured out the following plan: Moving a table from a room to another room can be done within 10 minutes. When moving a table from room i to room j, the part of the corridor between the front of room i and the front of room j is used. So, during each 10 minutes, several moving between two rooms not sharing the same part of the corridor will be done simultaneously. To make it clear the manager illustrated the possible cases and impossible cases of simultaneous moving.

For each room, at most one table will be either moved in or moved out. Now, the manager seeks out a method to minimize the time to move all the tables. Your job is to write a program to solve the manager’s problem.

 
Input
The input consists of T test cases. The number of test cases ) (T is given in the first line of the input. Each test case begins with a line containing an integer N , 1<=N<=200 , that represents the number of tables to move. Each of the following N lines contains two positive integers s and t, representing that a table is to move from room number s to room number t (each room number appears at most once in the N lines). From the N+3-rd line, the remaining test cases are listed in the same manner as above.
 
Output
The output should contain the minimum time in minutes to complete the moving, one per line.
 
Sample Input
3 4 10 20 30 40 50 60 70 80 2 1 3 2 200 3 10 100 20 80 30 50
 
Sample Output
10 20 30
 
数据 Input
75 154
125 158
176 48
196 65
21 171
15 170
17 100
61 116
3 189
98 104
112 19
163 66
42 14
81 168
53 165
36 143
84 140
105 199
195 151
 
数据 Input
 
解题思路
 
这题普遍有两种做法一种就是找到房间覆盖次数最多的数输出即可;一种是用贪心,也是因为开始学贪心我才开始找到这题的,没想到碰壁碰得那么严重,看关于贪心的相关资料后贪心的一个特点是找当前的最优值,当然这个部分最优值能够满足最终的整体最优值,所以这题我开始认为的时候是每次移动的时候找到尽可能多的可以同时移动的房间,这样到最后需要移动的次数会达到最小,我认为找到尽可能多的移动房间是当前的最优值,而尽可能找到最多房间的方法,无疑刚学贪心的童鞋都应该见过更典型的贪心基础的例子,比如说 活动安排问题(《计算机算法设计与分析》)等,这种尽可能找最多移动房间数目(也就是对应的最多的活动节目数量)就是根据活动结束的时间排序,因为这样才能为未安排活动留下尽可能多的时间,同样的道理,这题我选择按房间尾数小的数排序也是希望留下的走廊的路径长度更长使尽可能多的房间可以移动。
 
如果你说只给你一次移动的机会,要你找到移动尽可能多的房间,我这种按照尾数排序的方式跟活动安排的例子无异都是正确的,但是这题不一样,最终你是要将所有的需要移动的房间移完,对于活动安排这个例子,也就意味着你必须将活动节目表上的节目全部安排完,问你最少需要多少天,这是同样的概念。
 
在网上搜了题解,没有人说明到底为什么要按照房间首位置排序,当然我也没理由否认这是不行的,我按照房间尾数排序无非是我找到了这么一个理由——余留更多的走廊长度,所以我就选择了这个方法,后来找到了一个Case,也就是上面我放上去的测试数据,根据两种排序方式输出,发现前面房间的移动情况会影响接下来的房间移动,这两天想了一段时间也每个结果
 
我从另外一个角度想,如果按房间尾数排序的话,那么在第二次遍历的时候第一个找到的房间的起始号并不是最前的,这时不是最优的,你要从总体上来看,你以为每次找到尽可能多的房间,对一次的遍历从房间尾号排序确实达到了这样的目的,但你的整体目的不是这样的,因为你最终还是要把所有的房间找完,并不是说仅是找最多的一次,你还要顾及后面的让每一次都尽可能找得更多的房间。所以不管前几次怎样,你现在要找的这一次需要越靠前开始找。
 
形式上突然想到这题有点像0-1背包,你知道0-1背包是不能用贪心的方法解决的,下面是一个可以试用贪心算法解的题目,贪心解的确不错,可惜不是最优解。
  
[背包问题]
  有一个背包,背包容量是M=150。有7个物品,物品不可以分割成任意大小。要求尽可能让装入背包中的物品总价值最大,但不能超过总容量。
  
  物品 A   B   C   D  E   F  G  
  重量 35 30 60 50 40 10 25  
  价值 10 40 30 50 35 40 30  
 
分析:  
  目标函数: ∑pi最大  
  约束条件是装入的物品总重量不超过背包容量:∑wi<=M( M=150)  
 
(1)根据贪心的策略,每次挑选价值最大的物品装入背包,得到的结果是否最优?  
(2)每次挑选所占重量最小的物品装入是否能得到最优解?  
(3)每次选取单位重量价值最大的物品,成为解本题的策略。
  
值得注意的是,贪心算法并不是完全不可以使用,贪心策略一旦经过证明成立后,它就是一种高效的算法。
贪心算法还是很常见的算法之一,这是由于它简单易行,构造贪心策略不是很困难。
可惜的是,它需要证明后才能真正运用到题目的算法中。  
一般来说,贪心算法的证明围绕着:整个问题的最优解一定由在贪心策略中存在的子问题的最优解得来的。  
对于例题中的3种贪心策略,都是无法成立(无法被证明)的,解释如下:  
(1)贪心策略:选取价值最大者。  
反例: 
    W=30
    物品: A  B   C  
    重量:28 12 12
    价值:30 20 20  
根据策略,首先选取物品A,接下来就无法再选取了,可是,选取B、C则更好。
  
(2)贪心策略:选取重量最小。它的反例与第一种策略的反例差不多。  
 
(3)贪心策略:选取单位重量价值最大的物品。  
反例:  
    W=30
    物品: A  B   C  
    重量:28 20 10
    价值:28 20 10  
根据策略,三种物品单位重量价值一样,程序无法依据现有策略作出判断,如果选择A,则答案错误。
 
【注意:如果物品可以分割为任意大小,那么策略3可得最优解】
  对于选取单位重量价值最大的物品这个策略,可以再加一条优化的规则:对于单位重量价值一样的,则优先选择重量小的!这样,上面的反例就解决了。
  但是,如果题目是如下所示,这个策略就也不行了。  
  W=40  
  物品:A B C
  重量:25 20 15
  价值:25 20 15
  附:本题是个NP问题,用贪心法并不一定可以求得最优解,以后了解了动态规划算法后本题就有了新的解法。
 
上面这个例子很经典,它跟背包问题作对比说明贪心跟动态规划的区别,而杭电的这题是否也跟上面这个0-1背包有相同的地方,即我的做法是不是也是按第一种策略之后最后才得出错误的答案
 
尽力地说明最终还是要靠证明,抱歉,不会,所以如果你看了这个题解,然后知道怎样证明的话,希望你能够高抬贵手留下言,好让刚学贪心的我能够对此有深刻的理解
 
 #include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define SIZE 404 using namespace std; typedef struct item{
int begin, end;
}item;
item room[SIZE];
bool visit[SIZE];
int n; bool cmp(const item& a, const item& b)
{
return a.begin < b.begin;
} void Traverse(int cnt, int sum)
{
if(sum == n)
{
printf("%d\n", cnt*);
return;
}
int temp = , count = ;
for(int i=; i<n; ++i)
{
if(!visit[i] && temp < room[i].begin)
{
count++;
temp = room[i].end;
visit[i] = true;
}
}
Traverse(cnt+, sum+count);
} int main()
{
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
#endif
int T, left, right;
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
for(int i=; i<n; ++i)
{
scanf("%d", &left);
room[i].begin = left = left + (left % );
scanf("%d", &right);
room[i].end = right = right + (right % );
if(left > right)
{
room[i].begin = right;
room[i].end = left;
}
}
memset(visit, false, sizeof(visit));
sort(room, room+n, cmp);
Traverse(, );
}
}

HDU ACM 1050 Moving Tables的更多相关文章

  1. POJ 1083 &amp;&amp; HDU 1050 Moving Tables (贪心)

    Moving Tables Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) To ...

  2. HDOJ 1050 Moving Tables

    Moving Tables Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tot ...

  3. 1050 Moving Tables

    Moving Tables Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) To ...

  4. hdoj 1050 Moving Tables【贪心区间覆盖】

    Moving Tables Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tot ...

  5. hdu 1050 Moving Tables 解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1050 这道题目隔了很久才做出来的.一开始把判断走廊有重叠的算法都想错了.以为重叠只要满足,下一次mov ...

  6. --hdu 1050 Moving Tables(贪心)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1050 AC code: #include<stdio.h> #include<str ...

  7. hdu 1050 Moving Tables

    http://acm.hdu.edu.cn/showproblem.php?pid=1050 这个题我首先直接用的常规贪心,用的和那个尽可能看更多完整节目那种思路.但是.......一直WA....T ...

  8. HDU – 1050 Moving Tables

    http://acm.hdu.edu.cn/showproblem.php?pid=1050 当时这道题被放在了贪心专题,我又刚刚做了今年暑假不AC所以一开始就在想这肯定是个变过型的复杂贪心,但是后来 ...

  9. hdu 1050 Moving Tables (Greedy)

    Problem - 1050 过两天要给12的讲贪心,于是就做一下水贪心练习练习. 代码如下: #include <cstdio> #include <iostream> #i ...

随机推荐

  1. 谈谈map中的count方法

    map和set两种容器的底层结构都是红黑树,所以容器中不会出现相同的元素,因此count()的结果只能为0和1,可以以此来判断键值元素是否存在(当然也可以使用find()方法判断键值是否存在). 拿m ...

  2. ViewState压缩技术

    ViewState 的使用,大家可以说是又爱又恨,它其中一个特性就是保存页面的状态,对于只是展示的页面,我们可以直接在页面文件中使用 EnableViewState="false" ...

  3. UVa 11100 The Trip, 2007

    今天的教训:做题要用大块的时间来做,上午做一下,做题做到一半就去忙别的事,那么后面再做的时候就无限CE,WA了.因为你很难或者需要很长时间来找回当时的思路. 题意:就像套瓷娃娃一样,有n个包,大小可能 ...

  4. 剑指offer-第二章算法之斐波拉契数列(青蛙跳台阶)

    递归与循环 递归:在一个函数的内部调用这个函数. 本质:把一个问题分解为两个,或者多个小问题(多个小问题相互重叠的部分,会存在重复的计算) 优点:简洁,易于实现. 缺点:时间和空间消耗严重,如果递归调 ...

  5. 【转】不可变数组NSArray与可变数组NSMutableArray

    原文网址:http://www.jianshu.com/p/1ad327f56d1d 不可变数组NSArray //创建一个空数组 NSArray *array = [NSArray array]; ...

  6. Linux下基于HTTP协议带用户认证的GIT开发环境设置

    Git 的访问可以采用 HTTP 或 SSH 协议安全的访问,通常我们使用 gitlib 进行 Web 管理,但是在 Linux 命令行开发环境下,基本都是使用 SSH 协议,只需要在 gitlib ...

  7. perl环境配置以及Eclipse安装perl开发插件

    简介: 这篇文章将详细介绍 EPIC 组件的安装,EPIC 编辑环境,调试运行环境,着重介绍如何使用 EPIC 来快速.简便.准确地调试 Perl 语言程序,包括对于 Perl 程序的单步执行,断点用 ...

  8. core文件分析

    http://baidutech.blog.51cto.com/4114344/904419/ http://www.newsmth.net/pc/pccon.php?id=10001977& ...

  9. hdu 5469 Antonidas (dfs+剪枝)2015 ACM/ICPC Asia Regional Shanghai Online

    题意: 给出一棵树,再给出每个节点上的值(一个char字符)这些值以一个字符串s1表示,然后给出一个s2字符串,问在这棵树上是否存在两个点,从一个点走到另一个点所经过的路径上的char字符组成的字符串 ...

  10. HTML5中DOM元素的querySelector/querySelectorAll的工作机制

    在HTML5中,提供了强大的DOM元素选择API querySelector/querySelectorAll,允许使用JavaScript代码来完成类似CSS选择器的DOM元素选择功能.通常情况下, ...