zoukankan      html  css  js  c++  java
  • HDU-1051/POJ-1065 Wooden sticks 木棍子(动态规划 LIS 线型动归)

    嘤嘤嘤,实习半年多的小蒟蒻的第一篇博客(题解)

    英文的:

    There is a pile of n wooden sticks. The length and weight of each stick are known in advance. The sticks are to be processed by a woodworking machine in one by one fashion. It needs some time, called setup time, for the machine to prepare processing a stick. The setup times are associated with cleaning operations and changing tools and shapes in the machine. The setup times of the woodworking machine are given as follows:
    (a) The setup time for the first wooden stick is 1 minute.
    (b) Right after processing a stick of length l and weight w , the machine will need no setup time for a stick of length l' and weight w' if l <= l' and w <= w'. Otherwise, it will need 1 minute for setup.
    You are to find the minimum setup time to process a given pile of n wooden sticks. For example, if you have five sticks whose pairs of length and weight are ( 9 , 4 ) , ( 2 , 5 ) , ( 1 , 2 ) , ( 5 , 3 ) , and ( 4 , 1 ) , then the minimum setup time should be 2 minutes since there is a sequence of pairs ( 4 , 1 ) , ( 5 , 3 ) , ( 9 , 4 ) , ( 1 , 2 ) , ( 2 , 5 ) .

    Input
    The input consists of T test cases. The number of test cases (T) is given in the first line of the input file. Each test case consists of two lines: The first line has an integer n , 1 <= n <= 5000 , that represents the number of wooden sticks in the test case, and the second line contains 2n positive integers l1 , w1 , l2 , w2 ,..., ln , wn , each of magnitude at most 10000 , where li and wi are the length and weight of the i th wooden stick, respectively. The 2n integers are delimited by one or more spaces.

    Output
    The output should contain the minimum setup time in minutes, one per line.

    谷歌翻译:

    题目

    一堆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

    思路:拦截导弹(洛谷P1020)+友好城市(洛谷P2782),没有做过的需要提前做

    1.这道题乍一看是一个线性DP(因为既没有区间又没有树),根据l <= l'并且w <= w'的条件很容易就联想到求最大不下降子序列即LIS,但是细细一看发现这就是个拦截导弹(洛谷P1020,可以关注下我的博客)的加强版,如果我们只处理一边的数据,不过是让我们求出上升子序列的最小值,根据我们在拦截导弹中习得的Dilworth定理(最少链划分=最长反链长度),可以直接把这道题转化为求最长下降子序列的长度(不管是求最长上升还是下降还是不上升不下降都可以用nlogn的优化)

    2.表面上看大木棒子既有长度又有重量,其实我们可以把他直接当做结构体中的两个值进行处理,这就类似于之前我们做过的友好城市,只不过那道题里是连接南岸和北岸的桥,桥不能相交,而这道题中就是大木棒子的长度和重量,尽量使前一根木棒的长度重量小于后一根木棒的长度重量,所以我们可以先对结构体中的一个值进行排序,然后对另一个值进行LIS的处理

    注意:在我们第二步中对结构体的排序需要进行判等的处理,如果两个大木棒子的某一个值相等,就需要对这两根大木棒子另一个值判断,最后把较大值排在后面,以便做第一步的LIS。

    代码:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<cmath>
     5 #include<algorithm>
     6 using namespace std;
     7 const int maxn=5e3+5,INF=0x3f3f3f3f;//max别太大,亲测会MLE 
     8 int n,f[maxn],low1[maxn],low2[maxn],ans1=1,ans2=1;
     9 struct Node{
    10     int x,y;
    11 }a[maxn],b[maxn];
    12 bool cmp1(Node A,Node B){
    13     if(A.x==B.x)return A.y<B.y;//如果相等,让较小值排在前面,便于LIS的处理 
    14     return A.x<B.x;
    15 }
    16 bool cmp2(Node A,Node B){
    17     if(A.y==B.y)return A.x<B.x; 
    18     return A.y<B.y;
    19 }
    20 int main(){
    21 //    freopen("data.txt","r",stdin);
    22     int t;
    23     cin>>t;
    24     while(t--){
    25         cin>>n;
    26         memset(low1,0,sizeof(low1));
    27         memset(low2,0,sizeof(low2));
    28         memset(a,0,sizeof(a));//别忘了这里的预处理 
    29         memset(b,0,sizeof(b));
    30         ans1=ans2=1;//这里也是 
    31         for(int i=1;i<=n;i++){
    32             cin>>a[i].x;
    33             cin>>a[i].y;
    34             b[i].x=a[i].x;
    35             b[i].y=a[i].y;
    36         }//这里我为了防止暴毙,对木棒两个值都进行了LIS的处理 
    37         sort(a+1,a+n+1,cmp1);
    38         sort(b+1,b+n+1,cmp2);
    39         low1[1]=a[n].y,low2[1]=b[n].x;
    40         for(int i=n-1;i>=1;i--){//这里跟最长上升子序列的区别不大,细细体会 
    41             if(low1[ans1]<a[i].y)low1[++ans1]=a[i].y;
    42             else low1[lower_bound(low1+1,low1+ans1+1,a[i].y)-low1]=a[i].y;
    43         }
    44         for(int i=n-1;i>=1;i--){
    45             if(low2[ans2]<b[i].x)low2[++ans2]=b[i].x;
    46             else low2[lower_bound(low2+1,low2+ans2+1,b[i].x)-low2]=b[i].x;
    47         }
    48         cout<<min(ans1,ans2)<<endl;
    49     }//嘤嘤嘤 
    50 }

    没做拦截导弹和友好城市的一定要做噢

    --2020-04-06

  • 相关阅读:
    SAP系统管理中常见问题解答(转载)
    STMS传输队列中的请求状态一直是Running不能结束
    通过Tcode查找Badi或者客户出口
    通过LDB_PROCESS函数使用逻辑数据库
    ABAP读取长文本的方法
    SAP增强Enhancement
    ABAP开发顾问必备:SAP ABAP开发技术总结[转载]
    SAP事件 Event Flow(转载)
    jQuery中的text()、html()和val()以及javaScript中的innerText、innerHTML和value
    js访问对象属性的方式“.”与“[]”的区别
  • 原文地址:https://www.cnblogs.com/614685877--aakennes/p/12650077.html
Copyright © 2011-2022 走看看