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. 如何获取supersocket的源代码

    源代码的地址:https://github.com/kerryjiang/SuperSocket 安装git之后,可以使用命令行git clone https://github.com/kerryji ...

  2. JS 点击事件学习总结

    废话篇: 在我们编写无论什么网页内容的时候我们总是或多或少的要接触到点击事件这一范畴的,写过几个简短的demo和网页之后,感觉自己对电机事件一类的东西了解也更为的清楚了,之前写过很多零零散散的东西现在 ...

  3. Android中使用ListView实现分页刷新(线程休眠模拟)(滑动加载列表)

    当要显示的数据过多时,为了更好的提升用户感知,在很多APP中都会使用分页刷新显示,比如浏览新闻,向下滑动到当前ListView的最后一条信息(item)时,会提示刷新加载,然后加载更新后的内容.此过程 ...

  4. UVa 10161 Ant on a Chessboard

    一道数学水题,找找规律. 首先要判断给的数在第几层,比如说在第n层.然后判断(n * n - n + 1)(其坐标也就是(n,n)) 之间的关系. 还要注意n的奇偶.  Problem A.Ant o ...

  5. volley(2) 参数code : or_barcode, pr_ismsd:false , method:GET

    1. 来自于WHCombineBatchFragment.java /** * 当编辑框里面的内容完成的时候,自动的,同时获取服务器的批量数 */private void barcodeEnterEv ...

  6. OC获取文件(夹)的代码行数

    /* 考察NSString NSArray NSFileManager */ #import <Foundation/Foundation.h> /* 计算单个文件的代码行数 path:文 ...

  7. source导入错码解决办法

    mysql -uroot -p --default-character-set=utf8 test < D:/bak/1.sql

  8. singleton单例模式

    单例设计模式 单例设计模式概述    单例模式就是要确保类在内存中只有一个对象,该实例必须自动创建,并且对外提供    优点:    在系统内存中只存在一个对象,因此可以解决系统资源,对于一些需要频繁 ...

  9. struts2拦截器配置;拦截器栈;配置默认拦截器;拦截方法的拦截器MethodFilterInterceptor;完成登录验证

    struts2.xml 内容 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts ...

  10. 湖大 11404 manacher

    链接   http://acm.hunnu.edu.cn/online/?action=problem&type=show&id=11404&courseid=0 求 最长回文 ...