• 「洛谷P1233」木棍加工 解题报告


    P1233 木棍加工

    题目描述

    一堆木头棍子共有n根,每根棍子的长度和宽度都是已知的。棍子可以被一台机器一个接一个地加工。机器处理一根棍子之前需要准备时间。准备时间是这样定义的:

    第一根棍子的准备时间为1分钟;

    如果刚处理完长度为L,宽度为W的棍子,那么如果下一个棍子长度为Li,宽度为Wi,并且满足L>=Li,W>=Wi,这个棍子就不需要准备时间,否则需要1分钟的准备时间;

    计算处理完n根棍子所需要的最短准备时间。比如,你有5根棍子,长度和宽度分别为(4, 9),(5, 2),(2, 1),(3, 5),(1, 4),最短准备时间为2(按(4, 9)、(3, 5)、(1, 4)、(5, 2)、(2, 1)的次序进行加工)。

    输入输出格式

    输入格式:

    第一行是一个整数n(n<=5000),第2行是2n个整数,分别是L1,W1,L2,w2,…,Ln,Wn。L和W的值均不超过10000,相邻两数之间用空格分开。

    输出格式:

    仅一行,一个整数,所需要的最短准备时间。

    输入输出样例

    输入样例#1:

    5
    4 9 5 2 2 1 3 5 1 4
    

    输出样例#1:

    2
    

    思路

    一般来说,数据较大,要求顺序时,要优先考虑贪心(当然,也有可能是动态规划或其他算法,这并不绝对)。

    根据题意,最终答案中1min准备后能一次处理的木棍L、W非严递减。我们可以考虑以L为关键字进行降序排序,然后在W中进行类似于“导弹拦截”这道经典题的操作,也就是用最少的装置防御最多的导弹(请自行类比 导弹拦截 具体原因不再赘述)。

    总结一下,就是将L降序排序,然后求最长不下降子序列。

    废话不多说,直接上代码。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define MAXN 5005
    
    struct ppp{
        int L, W;
    }a[MAXN];
    
    bool cmp( ppp x, ppp y ){
        return x.L > y.L;
    }
    
    int n;
    int f[MAXN], tot;
    
    void Add( int x ){
        int l(1), r(tot), mid, ans(-1);
        while( l <= r ){
            mid = ( l + r ) >> 1;
            if ( f[mid] >= x ){
                r = mid - 1; ans = mid;
            } else l = mid + 1;
        }
        if ( ans == -1 ) f[++tot] = x;
        else f[ans] = x;
    }
    
    int main(){
        scanf( "%d", &n );
        for ( int i = 1; i <= n; ++i ) scanf( "%d%d", &a[i].L, &a[i].W );
        sort( a + 1, a + n + 1, cmp );
        f[++tot] = a[1].W;
        for ( int i = 2; i <= n; ++i ) Add( a[i].W );
        printf( "%d
    ", tot ); 
        return 0;
    }
    

    2018/11/26修改为Markdown格式

  • 相关阅读:
    Array.sort源码
    单例模式
    nio理解
    xoa中范型的应用
    mybatis 一对多映射 xml
    zookeeper
    java final
    spring controller里面返回JSONObject与返回String的不同
    synchronized的可重入性
    nio select poll epoll
  • 原文地址:https://www.cnblogs.com/louhancheng/p/10022981.html
Copyright © 2020-2023  润新知