这道题的数据(至少我们oj的)有问题!按照我下面的做法能够过数据,但并不是正解。(我在代码后面说一下这数据错哪里了。。)
二分图即可,也没必要拆点,其实只是把点视为两排,在左边一排向右边能连边的点连边(说白了就是左边点能放右边点后面),之后把右边点的link设为左边点。就这样。。考试时以为是dp,最后交了深搜。。。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int n, ans=0, idc=0;
int a[305][305],vis[305],l[305];
struct Book{int x, y;}book[305];
//inline bool cmp(Book x,Book y){return x.x==y.x?x.y>y.y:x.x>y.y;}
inline int find(int x)
{
for(int i=1;i<=n;i++)
if(!vis[i]&&a[x][i])
{
vis[i]=1;
if(!l[i]||find(l[i]))
{
l[i]=x;
return 1;
}
}
return 0;
}
int main(){
// freopen ("militarytraining.in", "r", stdin);
// freopen ("militarytraining.out", "w", stdout);
scanf("%d", &n);
for(int i=1; i<=n; i++)scanf("%d%d", &book[i].x, &book[i].y);
//sort(book+1, book+n+1,cmp);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(i!=j&&book[i].y>=book[j].y&&book[i].x>=book[j].x)
a[j][i]=1;
for(int i=1;i<=n;i++)
{
memset(vis,0,sizeof(vis));
ans+=find(i);
}
printf("%d
", n-ans);
}
二分图只能处理无DAG的情况,若存在DAG,对于这道题也就是完全相等的书之间可以互相放,但这种环会形成把1放在2后,并且2在1后面的灵异现象。说白了就是不对。所以要么拆成2×n个点,或者缩掉所有相等的点。呵呵。。。。