Poj_1083 Moving Tables(贪心,测试数据)

来源:互联网 发布:vuze mac下载 编辑:程序博客网 时间:2024/05/22 07:08

题意:

房间之间通过单通道抬桌子,一共有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

0 0
原创粉丝点击