POJ 1083 Moving Tables 思路 难度:0

http://poj.org/problem?id=1083

  这道题题意是有若干段线段,每次要求线段不重叠地取,问最少取多少次.

  因为这些线段都是必须取的,所以需要让空隙最小

思路:

  循环直到线段全部取完,对于某个刚取得线段ij,下一个线段km取起点k尽量靠近j且满足k>j的.记录循环次数cnt,答案是cnt*10

注意:

  房间是相对的,也就是说对于奇数房间号,利用的走廊相当于对应的偶数房间号开始的那一段路程,

  一段路程的开头不能是另外一段路程的结尾.

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 400;
int n;
typedef pair<int,int> P;
P a[maxn];
bool vis[maxn];
int main()
{
    freopen("data.in","r",stdin);
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(int i = 0;i < n;i++)
        {
            scanf("%d%d",&a[i].first,&a[i].second);
            if(a[i].first&1)a[i].first++;
            if(a[i].second&1)a[i].second++;
            if(a[i].first>a[i].second)swap(a[i].first,a[i].second);
        }
        sort(a,a+n);
        memset(vis,false,sizeof(vis));
        int cnt = 0;
        for(int st = 0;st < n;st++)
        {
            if(vis[st])continue;
            vis[st] = true;
            cnt++;
            for(int i = st + 1,e = a[st].second;i < n;i++)
            {
                if(a[i].first <= e || vis[i])continue;
                vis[i] = true;
                e = a[i].second;
            }
        }
        printf("%d
",cnt * 10);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/xuesu/p/4639739.html