hdu 1677 Nested Dolls 子串

题目:

A - Nested Dolls

Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

Submit Status

Description

Dilworth is the world’s most prominent collector of Russian nested dolls: he literally has thousands of them! You know, the wooden hollow dolls of different sizes

 of which the smallest doll is contained in the second smallest, and this doll is in turn contained in the next one and so forth. One day he wonders if there is 

another way of nesting them so he will end up with fewer nested dolls? After all, that would make his collection even more magnificent! He unpacks each nested doll 

and measures the width and height of each contained doll. A doll with width w1 and height h1 will fit in another doll of width w2 and height h2 if and only if w1 < w2 and 

h1 < h2. Can you help him calculate the smallest number of nested dolls possible to assemble from his massive list of measurements? 

 

Input

On the first line of input is a single positive integer 1 <= t <= 20 specifying the number of test cases to follow. Each test case begins with a positive integer 

1 <= m <= 20000 on a line of itself telling the number of dolls in the test case. Next follow 2m positive integers w1, h1,w2, h2, . . . ,wm, hm, where wi is the 

width and hi is the height of doll number i. 1 <= wi, hi <= 10000 for all i. 

 

Output

For each test case there should be one line of output containing the minimum number of nested dolls possible. 

 

Sample Input

4

3

20 30 40 50 30 40

4

20 30 10 10 30 20 40 50

3

10 30 20 20 30 10

4

10 10 20 30 40 50 39 51 

 

Sample Output

1

2

3

题目大意:

给n个娃娃,让你按照长和宽来嵌套,求最多形成几个娃娃.注:被嵌套的不算一个.长宽不能交换.长等于宽不能交换

题目思路:

1、先将长从大到小排列,使其变成一维问题

2、利用最长单调序列求答案

题目优化

1、如果只用最长单调子序列求,可能会超时,所以可以二分答案

2、但如果题目时间要求短用二分搜索答案还是可能超时

3、所以采用反最长单调递增子序列( 最长单调非递减子序列)

4、分析:假设长按照单调递减来求,简化为下图.如果前面的高于后面的,后面必然会在他的子序列里面,否则就ans++; 这样就转化为求最长单调非递减子序列

55

3 3

2 2

程序:

 

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cctype>
#include <fstream>
#include <limits>
#include <vector>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <cassert>
using namespace std;
int b[30000];
struct node
{
    int x,y;

} a[30000];
bool cmp(node a,node b)//按长排序从小到大
{
    if(a.x!=b.x)
        return a.x<b.x;
    else return a.y>b.y;
}
int main()
{
    int ci,n;
    scanf("%d",&ci);
    while(ci--)
    {
        scanf("%d",&n);
        for(int i=1; i<=n; i++)
        {
            scanf("%d%d",&a[i].x,&a[i].y);
        }
        sort(a+1,a+n+1,cmp);
        b[1]=1;
        int ans=0,time=0,len=1;
        for(int i=2; i<=n; i++)//最长单调非递减子序列
            if(a[i].x==a[b[len]].x||a[i].y<=a[b[len]].y)
            {
                len++;
                b[len]=i;
            }
            else//维护序列数组
            {
                for(int j=1; j<=len; j++)
                    if(a[i].y>a[b[j]].y)
                    {
                        b[j]=i;
                        break;
                    }
            }
            printf("%d\n",len);
    }
return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值