3359: [Usaco2004 Jan]矩形
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 74 Solved: 37
[ Submit][ Status][ Discuss]
Description
给出N个矩形(1≤N≤100)和它的长和宽(不超过1000),写一个程序找出最大的K,使得
有K个矩形满足层层包含的关系,即里层的矩形被所有外层的矩形包含.一个矩形P1包含另一个
矩形P2,则P2的一边小于P1的一边,并且P9的另一边不超过P1的另一边.如果两个矩形相同,视
为不包含.如2 x 1的矩形被2x2的矩形包含,不被1 x 2的矩形包含.
注意:矩形的顺序可以是任意的,且矩形可以旋转.
Input
第1行:整数N.
第2到N+1行:矩形的长和宽,均为整数.
Output
一行,输出最大的包含数K.
Sample Input
4
8 14
16 28
29 12
14 8
8 14
16 28
29 12
14 8
Sample Output
2
经典题,LIS的变种
因为矩形可以旋转,所以如果矩形的长<宽,那么交换矩形的长和宽
之后按矩形的宽排序,dp[i]表示以第i个矩形为最外层嵌套能最多套多少层
转移:dp[i] = max(dp[j]+1,第j个矩形能被第i个嵌套)
#include<stdio.h>
#include<algorithm>
using namespace std;
typedef struct Res
{
int x, y;
bool operator < (const Res &b) const
{
if(x<b.x || x==b.x && y<b.y)
return 1;
return 0;
}
}Res;
Res s[105];
int dp[105];
int main(void)
{
int n, i, j, ans;
scanf("%d", &n);
for(i=1;i<=n;i++)
{
scanf("%d%d", &s[i].x, &s[i].y);
if(s[i].x>s[i].y)
swap(s[i].x, s[i].y);
}
ans = 0;
sort(s+1, s+n+1);
for(i=1;i<=n;i++)
{
dp[i] = 1;
for(j=1;j<=i-1;j++)
{
if(s[j].x<=s[i].x && s[j].y<=s[i].y && (s[i].x!=s[j].x || s[i].y!=s[j].y))
dp[i] = max(dp[i], dp[j]+1);
}
ans = max(ans, dp[i]);
}
printf("%d\n", ans);
return 0;
}