描述
有n个矩形,每个矩形可以用a,b来描述,表示长和宽。矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅当a
分析:
矩形之间的“可嵌套”关系是一个典型的二元关系,二元关系可以用图来建模。如果矩形X可以嵌套在矩形Y里,就从X到Y连一条有向边。这个有向图是无环的,因为一个矩形无法直接或间接嵌套在自己内部。换句话说,就是求DAG的最长路径。
设d(i)表示从结点i出发的最长路径长度
d(i)=max{d(j)+1|(i,j)∈E}
题目来源:http://acm.nyist.net/JudgeOnline/problem.php?pid=16
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100000+9;
int d[maxn];
int n;
struct{
int h,w;
}rec[maxn];
bool edge(int i,int j)
{
return (rec[i].h>rec[j].h&&rec[i].w>rec[j].w)||(rec[i].h>rec[j].w&&rec[i].w>rec[j].h);
}
//记忆化搜索
int dp(int i)
{
int& ans=d[i];
if(ans>0) return ans;
ans = 1;
for(int j = 1;j<=n;j++)
if(edge(i,j)) ans = max(ans,dp(j)+1);
return ans;
}
void print_ans(int i)
{
printf("%d ",i);
for(int j = 1;j<=n;j++)
if(edge(i,j)&&d[i]==d[j]+1)
{
print_ans(j);
break;
}
}
int main()
{
int T;
cin>>T;
while(T--)
{
cin>>n;
memset(d,-1,sizeof(d));
for(int i =1 ; i<=n ; ++i)scanf("%d %d",&rec[i].h,&rec[i].w);
for(int i =1;i <= n;++i) dp(i);
int m =1 ;
for(int i=2;i<=n;i++)
{
if(d[m]<d[i]) m=i;
}
/*print_ans(m);
printf("\n");*/
cout<<d[m]<<endl;
cout<<endl;
}
return 0;
}