矩形嵌套问题
问题描述:输入多个矩形的长和宽。矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅当a < c,b < d或者b < c,a < d,任务是选出尽可能多的矩形排成一行,使得除了最后一个之外,每一个矩形都可以嵌套在下一个矩形内求出最多嵌套矩形的个数。
注意加粗的一段话,就要求我们必须先排序。
样例输入:
1
10
1 2
2 4
5 8
6 10
7 9
3 1
5 8
12 10
9 7
2 2
样例输出:
5
分析:
这个问题是不是和最长递增子序列的问题十分类似。
只不过这个子序列的数不只是一个数,而是长和宽罢了。
所以只要会转换一下就十分简单了。
依然按照分析动态规划的3个步骤:
按照3个步骤:
1.刻画最优解结构特征:
定义dp[i]为以第i个矩形pi为末尾的整个矩形序列中能够被嵌套的最多数目2.递归地定义最优解的值:
以第i个矩形pi为末尾元素的序列是:
1.只包含第i个矩形pi的序列
2.如果满足j < i 并且 pj.l < pi.l && pj.w < pi.w这个条件的以pj为末尾的序列末尾再加上pi后得到的新序列。
这两者之一。
所以得到此递推式:
dp[i] = max(dp[i],dp[j]+1) (j < i 且 pj.l < pi.l && pj.w < pi.w)3.计算最优解的值(递推)
代码如下:
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 100;
struct P{
int l,w;
}p[maxn];
int max(int a,int b)
{
return a>b?a:b;
}
int min(int a,int b)
{
return a<b?a:b;
}
int cmp(const P& a,const P& b)
{
if(a.l<b.l) return 1;
else if(a.l==b.l&&a.w<b.w) return 1;
else return 0;
}
int dp[maxn];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
int a,b;
scanf("%d%d",&p[i].l,&p[i].w);
a = max(p[i].l,p[i].w);
b = min(p[i].l,p[i].w);
p[i].l = a; p[i].w = b;//长大于宽
}
sort(p,p+n,cmp);
for(int i=0;i<n;i++)
{
dp[i] = 1;
for(int j=0;j<=i;j++)
{
if(p[j].l<p[i].l&&p[j].w<p[i].w)
{
dp[i] = max(dp[i],dp[j]+1);
}
}
}
int ans=dp[0];
for(int i=0;i<n;i++)
{
if(ans<dp[i])
ans = dp[i];
}
printf("%d\n",ans);
}
return 0;
}