http://poj.org/problem?id=1083
参见 白书选择不相交区间问题
选择不相交区间问题 中,要选尽可能多的区间覆盖整段, 是根据右端点从小到大排序,这样能得到的是局部最优解,由于只需要做一次,所以此处局部最优解也是全局最优解。
而对于本题,选择的过程是多次的,因此按照上面的贪心法则 会出现 下面的情况:
在当前的局部贪心过程中,【1,5】、【2,4】都是可以选的, 按照 【选择不相交区间问题 】会选【2,4】这个区间, 而这样 会导致 【1,1】这段空间浪费了,那么在下一次的局部贪心中 ,只能选【1,5】了,如果此时前面的区间需要用到 【1,1】这部分,却发现被 【1,5】占用了,那么就不能同时选上了。。就无法达到全局最优。
如果我们按照 左端点从小到大排序,那么我们就可以避免 【区间左边部分被浪费掉】的情况, 而右边部分的先后,是不影响答案的。
-------还有个方案,直接数出 被覆盖过次数最多的点,就是答案了。。。。
#include <cmath>
#include <cstdio>
#include <cstring>
#include <limits>
#include <string>
#include <iostream>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
using namespace std;
const int inf=2147483647;
int min(int a,int b){return a<b?a:b;}
int min(int a,int b,int c){return min(min(a,b),c);}
struct node
{
int x,y;
};
node tm[205];
bool cmp(node a,node b)
{
return a.x<b.x;
}
int main()
{
int t;cin>>t;
int n;
int i;
int x,y;
while(t--)
{
scanf("%d",&n);
for (i=1;i<=n;i++)
{
scanf("%d%d",&x,&y);
if (y%2) y++;
if (x%2) x++;
x/=2;
y/=2;
if (x>y)
swap(x,y);
tm[i].y=y;
tm[i].x=x;
}
sort(tm+1,tm+1+n,cmp);
int cun=0;
int used[205];
int j;
int ans=0;
memset(used,0,sizeof(used));
int tmp_n=n;
while(cun<n)
{
int ok=0;
for (i=1;i<=tmp_n;i++)
{
if (used[i]==0)
tm[++ok]=tm[i];
}
tmp_n=ok;
memset(used,0,sizeof(used));
ans++;
int last=0;
for (i=1;i<=ok;i++)
{
node tmp=tm[i];
if (tmp.x<=last) continue;
last=tmp.y;
used[i]=1;
cun++;
}
}
printf("%d\n",ans*10);
}
return 0;
}