• Wooden Stricks——两个递增条件的线性DP


    题目

    一堆n根木棍。每个棒的长度和重量是预先已知的。这些木棒将由木工机械一一加工。机器需要准备一些时间(称为准备时间)来准备处理木棍。设置时间与清洁操作以及更换机器中的工具和形状有关。木工机械的准备时间如下: 
      (a)第一个木棍的准备时间为1分钟。
      (b)在处理长度为l和重量为w的棒之后,如果l <= l'并且w <= w',则机器将不需要设置长度为l'和重量为w'的棒的设置时间。否则,将需要1分钟进行设置。
    您将找到处理给定的n根木棍的最短准备时间。例如,如果您有五根长度和重量对分别为(9,4),(2,5),(1、2),(5、3)和(4,1)的摇杆,则最小设置时间应该是2分钟,因为有对(4,1),(5,3),(9,4),(1,2),(2,5)对的序列。

    输入值

    输入包含T个测试用例。在输入文件的第一行中给出了测试用例的数量(T)。每个测试用例由两行组成:第一行具有整数n,1 <= n <= 5000,代表测试例中木棍的数量,第二行包含2n个正整数l1,w1,l2, w2,...,ln,wn,每个大小最大为10000,其中li和wi分别是第i个木棍的长度和重量。2n个整数由一个或多个空格分隔。

    输出量

    输出应包含以分钟为单位的最短建立时间,每行一条。

    样本输入

    3 
    5 
    4 9 5 2 2 1 3 5 1 4 
    3 
    2 2 1 1 2 2 
    3 
    1 3 2 2 3 1 
    

    样本输出

    2
    1
    3


    分析
    首先理解题目大意,不难看出,需要求最长上升子序列,不过这道题特殊在,要维护两个条件同时递增。
    既然要两个条件要同时满足,那就先预处理,使其中已经满足了一个条件,再在此基础上去考虑另一个条件不就好了吗?就是一道线性DP
    代码
    对数据的处理:
      (其中flag用于表示是否已经被放进了某一个子序列中)
    struct node{
        int l;
        int w;
        bool flag;
    }sticks[5005];
    
    bool cmp(node a,node b){
        if(a.l!=b.l)
            return a.l > b.l;
        else
            return a.w > b.w;
    }
    此时已经处理好其中一项条件,再继续处理第二个条件,找出反链即可(和导弹拦截相似但并不一样,这个顺序已经固定)
            sort(sticks,sticks+n,cmp);
            int ans = 0,min;
            for(int i = 0; i < n; i++){
                if(sticks[i].flag) continue;
                min = sticks[i].w;
               for(int j = i+1; j < n; j++){
                  if(min >=sticks[j].w && !sticks[j].flag){
                         min = sticks[j].w;
                         sticks[j].flag = true;
                    }
                }
                 ans++;
           } 
           printf("%d
    ",ans);  
    
    

    关键点就这些了

    谢谢浏览

     
  • 相关阅读:
    webpack初识
    Vue+ElementUi项目实现表格-单行拖拽
    promise/async与await 的执行顺序梳理
    MDN社区
    angularjs中的异步操作
    javascript中的字符串和数组的互转
    angularjs的练习题
    angularjs基础知识
    开发的两种方式
    ASP.NET中的HttpClient发送请求
  • 原文地址:https://www.cnblogs.com/hhhhalo/p/12653713.html
Copyright © 2020-2023  润新知