1084: 矩形嵌套问题
Description
有n个矩形,每个矩形可以用两个整数a,b描述,表示它的长和宽。矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅当a
Input
每组测试数据的第一行是一个正整数n,表示该组测试数据中含有矩形的个数(n<=1000)
随后的n行,每行有两个数a,b(0
Output
每组测试数据都输出一个数,表示最多符合条件的矩形数目,每组输出占一行
Sample Input
10
1 2
2 4
5 8
6 10
7 9
3 1
5 8
12 10
9 7
2 2
Sample Output
5
题解:
经典DAG模型
当然用LIS更容易TAT
AC代码
DAG
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define CLR(a,b) memset(a,(b),sizeof(a))
const int N = 1e3+5;
int G[N][N];
int dp[N];
int arr[N], brr[N];
int n;
int solve(int i)
{
int& ans = dp[i]; //引用 也就是 ans相当于dp[i]
if(ans > 0) return ans; // 记忆化搜索
ans = 1;
for(int j = 1; j <= n; j++) {
if(G[i][j]) {
ans = max(ans,solve(j)+1);
}
}
return ans;
}
//void print_ans(int i) // 字典序最小方法
//{
//
// for(int j = 1; j ,+ n; j++) {
// if(v[i][j] && dp[i]==dp[j]+1) {
// print_ans(j); break;
// }
// }
//}
int main()
{
while(~scanf("%d",&n)) {
for(int i = 1;i <= n; i++) {
scanf("%d%d",&arr[i],&brr[i]); //arr[i]为长
if(arr[i] < brr[i])
swap(arr[i],brr[i]);
}
//建图 V[i][j]表示i可以嵌套在里面
//dp[i] 表示 从节点i出发可以到达的最大路径 dp[i] = max(dp[i],dp[j]+1)
CLR(G,0); CLR(dp,0);
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
if(arr[i]<arr[j] && brr[i]<brr[j]) {
G[i][j] = 1;
}
}
}
int res, ans = 0;
for(int i = 1; i <= n; i++) {
if(solve(i) > ans) {
ans = dp[i];
res = i;
}
}
printf("%d\n",ans);
// print_ans(res);
// printf("\n");
}
return 0;
}
LIS
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define CLR(a,b) memset(a,(b),sizeof(a))
const int N = 1e3+10;
int dp[N];
struct node {
int a, b;
}p[N];
bool cmp(node x,node y)
{
if(x.b != y.b) return x.b < y.b;
return false;
}
int main()
{
int n;
while(~scanf("%d",&n)) {
for(int i = 1; i <= n; i++) {
scanf("%d%d",&p[i].a,&p[i].b);
if(p[i].a < p[i].b) swap(p[i].a,p[i].b);
dp[i] = 1;
}
sort(p+1,p+1+n,cmp);
int ans, k = 1;
for(int i = 2; i <= n; i++) {
ans = 0;
for(int j = 1; j < i; j++) {
if(p[i].a>p[j].a && p[i].a>p[j].a) {
ans = max(dp[j],ans);
}
}
dp[i] = ans+1;
k = max(dp[i],k);
}
printf("%d\n",k);
}
return 0;
}