Poj_1083 Moving Tables(贪心,测试数据)
2016-12-12 21:20
393 查看
题意:
房间之间通过单通道抬桌子,一共有400个房间,分别按照图上顺序编号。每次交换需要10分钟,当两个交换路径不重叠时可以在同一个时间间隔内完成。给出所有的搬动需求,问最少需要的时间。
思路:
最开始的思路就是模拟,首先把两边归为一边,按起点将所有交换排序后,每次都贪心的拿一遍,这样最后可以得到拿的次数。因为数据量不大,即便是O(n^2)的时间复杂度也不会超时,所以很快写出来了。但是却WA的很惨。。。虽然对贪心的思路不太确定,但是没找到反例。
后来参考了网上的做法,基本上都是遍历每一个交换区间,用一个数组记录过道i被遍历的次数,这样遍历次数最多的那个区间的次数乘以10,就是最少需要的时间。这个思路的证明可以参考这个回答:http://poj.org/showmessage?message_id=347563
这个思路确实十分巧妙,但是我还是一直在纠结我的算法为什么会错。尝试着证明了一下,发现对于经过次数最多的那个过道,我的每一次遍历也是一定经过它的,并且遍历的次数也不可能小于经过这个过道的次数(每次最多拿一个),所以也就是说遍历的次数一定等于经过次数最多的过道的次数,也就是说两个算法是等价的。后面经过调试发现思路确实是对的,WA在了中间对于每次遍历点的标记。
这道题收获还是很多的,坚持了自己的算法没有盲从,并且最后通过调试得到了证明。两个算法在时间复杂度上想通,我的空间复杂度可能更到一些,但是思路更加直接,如果是比赛的时候的话还是直接点好吧。
PS:中间cb罢工无法调试,搞了半天解决不了,结果搁置了两天自己好了。。。终于把这道题给debug了出来。
代码实现:
测试样例:
http://poj.org/showmessage?message_id=119066
房间之间通过单通道抬桌子,一共有400个房间,分别按照图上顺序编号。每次交换需要10分钟,当两个交换路径不重叠时可以在同一个时间间隔内完成。给出所有的搬动需求,问最少需要的时间。
思路:
最开始的思路就是模拟,首先把两边归为一边,按起点将所有交换排序后,每次都贪心的拿一遍,这样最后可以得到拿的次数。因为数据量不大,即便是O(n^2)的时间复杂度也不会超时,所以很快写出来了。但是却WA的很惨。。。虽然对贪心的思路不太确定,但是没找到反例。
后来参考了网上的做法,基本上都是遍历每一个交换区间,用一个数组记录过道i被遍历的次数,这样遍历次数最多的那个区间的次数乘以10,就是最少需要的时间。这个思路的证明可以参考这个回答:http://poj.org/showmessage?message_id=347563
这个思路确实十分巧妙,但是我还是一直在纠结我的算法为什么会错。尝试着证明了一下,发现对于经过次数最多的那个过道,我的每一次遍历也是一定经过它的,并且遍历的次数也不可能小于经过这个过道的次数(每次最多拿一个),所以也就是说遍历的次数一定等于经过次数最多的过道的次数,也就是说两个算法是等价的。后面经过调试发现思路确实是对的,WA在了中间对于每次遍历点的标记。
这道题收获还是很多的,坚持了自己的算法没有盲从,并且最后通过调试得到了证明。两个算法在时间复杂度上想通,我的空间复杂度可能更到一些,但是思路更加直接,如果是比赛的时候的话还是直接点好吧。
PS:中间cb罢工无法调试,搞了半天解决不了,结果搁置了两天自己好了。。。终于把这道题给debug了出来。
代码实现:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> using namespace std; struct Node{ int sta; int en; }; const int MAX = 210; bool cmp(const Node& n1, const Node& n2){ if( n1.sta != n2.sta ){ return n1.sta<n2.sta; } return n1.en<n2.en; } int T; int N; int res; Node lis[MAX]; bool flag[MAX]; int path[MAX]; int main(){ scanf("%d",&T); while( T-- ){ scanf("%d",&N); int a,b; res = 0; memset(flag,false,sizeof(flag)); for( int i = 0; i < N; i++ ){ scanf("%d%d",&a,&b); if( a%2 == 0 ){ a /= 2; } else{ a = (a-1)/2+1; } if( b%2 == 0 ){ b /= 2; } else{ b = (b-1)/2+1; } if( a > b ){ swap(a,b); } lis[i].sta = a; lis[i].en = b; } int pos = 0; int dis = 0; sort(lis,lis+N,cmp); for( int i = 0; i < N; i++ ){ if( flag[i] == true ){ continue; } pos = i+1; flag[i] = true; dis = lis[i].en; res++; while( pos < N ){ if( flag[pos] == true ){ pos++; continue; } if( lis[pos].sta > dis ){ flag[pos] = true; dis = lis[pos].en; } pos++; } } printf("%d\n",res*10); } return 0; }
测试样例:
http://poj.org/showmessage?message_id=119066
相关文章推荐
- POJ 1083 Moving Tables 贪心
- POJ- 1083-Moving Tables-贪心
- POJ 1083 Moving Tables(贪心)
- 【贪心】Moving Tables POJ 1083
- POJ 1083 && HDU 1050 Moving Tables (贪心)
- POJ 1083 Moving Tables (贪心)
- POJ 1083 && HDU 1050 Moving Tables(贪心)
- POJ 1083 && HDU 1050 Moving Tables (贪心)
- POJ 1083 Moving Tables(贪心!!)
- poj 1083 Moving Tables_dp
- Moving Tables--POJ 1083
- poj 1083 Moving Tables
- poj-1083-Moving Tables(hdu-1050)
- POJ1083,Moving Tables,好纠结的题
- POJ 1083 Moving Tables
- POJ 1083 Moving Tables(水题)
- poj 1083 Moving Tables
- POJ 1083 Moving Tables 思路 难度:0
- POJ-1083-Moving Tables-2013-11-26 16:43:58
- POJ 1083 Moving Tables (水题)