nyoj1255 - Rectangles - LIS变形(详解)

Rectangles

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 2
描述

Given N (4 <= N <= 100)  rectangles and the lengths of their sides ( integers in the range 1..1,000), write a program that finds the maximum K for which there is a sequence of K of the given rectangles that can "nest", (i.e., some sequence P1, P2, ..., Pk, such that P1 can completely fit into P2, P2 can completely fit into P3, etc.).

 

A rectangle fits inside another rectangle if one of its sides is strictly smaller than the other rectangle's and the remaining side is no larger.  If two rectangles are identical they are considered not to fit into each other.  For example, a 2*1 rectangle fits in a 2*2 rectangle, but not in another 2*1 rectangle.

 

The list can be created from rectangles in any order and in either orientation.

输入
The first line of input gives a single integer, 1 ≤ T ≤10, the number of test cases. Then follow, for each test case:

* Line 1: a integer N , Given the number ofrectangles N<=100
* Lines 2..N+1: Each line contains two space-separated integers X Y, the sides of the respective rectangle. 1<= X , Y<=5000
输出
Output for each test case , a single line with a integer K , the length of the longest sequence of fitting rectangles.
样例输入
148 1416 2829 1214 8
样例输出
2
来源
第七届河南省程序设计大赛
上传者
516108736

分析:

我真是WA了无数次啊,没读懂题意,所以说题意还是很重要得,我认为的两个坑点:

(1)“A rectangle fits inside another rectangle if one of its sides is strictly smaller than the other rectangle's and the remaining side is no larger.  ”这里的边是任意的意思,而不是长对应长,宽对应宽,只要有第一个长方形的一边小于第二个长方形的一边,第一个长方形的另一边小于等于第二个长方形的另一边就行了,不用非要长对应长,宽对应宽。

(2)“The list can be created from rectangles in any order and in either orientation.”这句话可以说是非常重要了,可以以任何次序和任何方向,就是说,可以向前,也可以向后(把题目理解成,正序一遍,逆序一遍了,WA了几次……)。

比如:

1 2

3 5

2 4

1 1

输出:4

通过上边的例子可以知道“以任何次序任何方向”是什么意思了吧……

总结:这种可以方向改变的,我们不如输入的时候,第一个值存小的,第二个值存大的,给它排序,让第一个数小的在前,若同样大,让第二个数小的在前,这样用LIS模板就可以求出结果了。

代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>

using namespace std;
typedef pair<int,int> P;
P a[103];
int dp[103];

int cmp(P x,P y){
    if(x.first!=y.first)return x.first<y.first;
    else return x.second<y.second;
}

int judge(P x,P y){
    if(x.first<=y.first&&x.second<y.second||x.first<y.first&&x.second<=y.second)return 1;
    return 0;
}

int main(){
    int t,n,x,y;
    scanf("%d",&t);
    while(t--){
        memset(a,0,sizeof(a));
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%d%d",&x,&y);
            if(x>y){a[i].first=y;a[i].second=x;}
            else {a[i].first=x;a[i].second=y;}
            dp[i]=1;
        }
        sort(a,a+n,cmp);
        int res=0;
        for(int i=0;i<n;i++){
            for(int j=0;j<i;j++){
                if(judge(a[j],a[i])){
                    dp[i]=max(dp[i],dp[j]+1);
                }
            }
            res=max(res,dp[i]);
        }

        printf("%d\n",res);
    }
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值