zoukankan      html  css  js  c++  java
  • hust 1463

    题目描述

    m个盒子,第i个盒子的长尾hi,宽为wi。如果两个盒子i,j满足hi<hjwi<wj,则盒子i能够放入盒子j。按照上述要求堆放盒子,则最少能剩下多少堆?

    输入

    第一行有一个正整数 t ,表示数据组数(不多于20)。每组数据第一行为m,表示盒子个数,1 ≤ m ≤ 20000。接下来一样有2m个正整数w1h1,w2h2, ... ,wmhm,分别表示盒子尺寸。其中对于任何i,1 ≤ wihi ≤ 10000. 

    输出

    每一组测试数据输出一样,为最少的堆数。

    样例输入

    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
    

    样例输出

    1
    2
    3
    2
    看到题目大家都觉得很熟悉,不就是dp问题吗?可是n=20000;不能用n^2的dp,只能用nlgn的方法
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int maxn=20001;
    struct node
    {
        int x,y;
    }box[maxn];
    int a[maxn];
    bool cmp(node xx,node yy)
    {
        if (xx.x==yy.x) return xx.y<yy.y;
        else return xx.x>yy.x;
    }
    void find(int x,int y,int v)
    {
        while (x<y)
        {
            int m=x+(y-x)/2;
            if (a[m]<=v) x=m+1;
            else y=m;
        }
        a[x]=v;
    }
    int main()
    {
        int n,len,t;
        scanf("%d",&t);
        while (t--)
        {
            scanf("%d",&n);
            for (int i=1;i<=n;i++)
            scanf("%d%d",&box[i].x,&box[i].y);
            sort(box+1,box+n+1,cmp);
            len=1;a[1]=box[1].y;
            for (int i=2;i<=n;i++)
            {
                if (box[i].y>=a[len]) a[++len]=box[i].y;
                else
                {
                    find(1,len,box[i].y);
                }
            }
            printf("%d
    ",len);
        }
        return 0;
    }
    至少做到我努力了
  • 相关阅读:
    luogu P1144 最短路计数
    luogu P1440 求m区间内的最小值
    cogs 1075. [省常中2011S4] 最短路径问题
    luogu P2485 [SDOI2011]计算器
    luogu P1220 关路灯
    笨小猴 2008年NOIP全国联赛提高组
    [CF580E]Kefa and Watch
    [HDU2138]How many prime numbers
    [NOIp2014提高组]解方程
    [洛谷1390]公约数的和
  • 原文地址:https://www.cnblogs.com/chensunrise/p/3731086.html
Copyright © 2011-2022 走看看