zoukankan      html  css  js  c++  java
  • HDU 1051 Wooden Sticks

    一、题目概述

    Wooden Sticks

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 23470    Accepted Submission(s): 9526


    Problem Description
    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 (4,9), (5,2), (2,1), (3,5), and (1,4), then the minimum setup time should be 2 minutes since there is a sequence of pairs (1,4), (3,5), (4,9), (2,1), (5,2).
     
    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 n 2 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.
     
    Sample Input
    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
     
    Sample Output
    2 1 3
     
    Source
     

    二、题目释义

    给你一堆具有长度和重量的木头,让你去机器里加工,机器会有一个一分钟的set时间,首次加工需要set一次,当连续放入的木头不满足后者的长度和重量都大于等于前者时,机器需要set一下,让你求出最短的set时间(不用求出序列)

    三、思路分析

    我们会非常直观的想到从小到大进行排序,但很遗憾,长度和重量我们都必须考虑,我们无法对两个主元进行排序操作,但是要让机器set时间最短,其必然要满足某一个元素如长度是从小到大排序的,这是最优解的必要条件,那我们便可以对长度进行排序,对重量进行贪心。

    确定使用贪心策略,最关键的有两步,一步即设计贪心策略,二即证明由贪心得到的局部最优解最优解即为整体最优解

    贪心策略:排序之后扫描一遍stick,将满足条件的stick标记为vis[i] = 1,即已经被使用,不满足条件的stick为未使用,(需要注意的是当遇到不满足的stick时,扫描比较应当是比较不符合前一个与不符合后一个)扫描到尾部之后,再从第一个未使用的stick开始,扫描一遍全部未使用的stick重复之前的操作,直到全部stick都被使用,每扫描一次计数+1

    证明:贪心策略所得到为每一次尽可能大的子串,每次对子串取尽可能大,所得到即为最少的子串个数

    四、AC代码

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cstring>
     5 using namespace std;
     6 
     7 const int N = 5005;
     8 struct stick
     9 {
    10     int len,wei;
    11 }a[N];
    12 
    13 int vis[N];
    14 
    15 bool cmp(stick a, stick b)
    16 {
    17     if(a.len == b.len)
    18         return a.wei < b.wei;
    19     else return a.len < b.len;
    20 }
    21 
    22 int main()
    23 {
    24     int T,n; cin >> T;
    25     int flag;
    26     while(T--)
    27     {
    28         cin >> n;
    29         memset(vis,0,sizeof(vis));
    30         for(int i=0; i<n; i++)
    31             scanf("%d%d",&a[i].len,&a[i].wei);
    32         sort(a,a+n,cmp);
    33         for(int i=0; i<n; i++)
    34         {
    35             printf("%d %d ",a[i].len,a[i].wei);
    36         }
    37         cout << endl;
    38         int st=0, cnt=0;
    39         vis[0] = 1;
    40         while(st<n)
    41         {
    42             cnt++; flag = 1;
    43             for(int j=st,i=st+1; i<n; i++)
    44             {
    45                 if(vis[i]) continue;
    46                 if(a[j].wei<=a[i].wei)
    47                 {
    48                     vis[i] = 1;
    49                     j = i; // 这一步实现,只有符合了条件,比较的stick才会依次向前迭代
    50                 }
    51                 else
    52                 {
    53                     if(flag) // 这里的flag用来确定只有在这一遍扫描中,只有第一个未使用的会被标记st,以作为下一次的起点
    54                     {
    55                         st = i;
    56                         flag = 0;
    57                     }
    58                 }
    59             }
    60             if(flag) break;
    61         }
    62         cout << cnt << endl;
    63     }
    64     return 0;
    65 }
  • 相关阅读:
    python面向对象三大特性之一封装
    python面向对象的三大特性之一多态
    python之子类调用父类的两种方式
    python之接口继承
    python之组合与继承的使用场景
    Learning to Rank Short Text Pairs with Convolutional Deep Neural Networks(paper)
    lesson9-小象学院cv
    tips
    C5-fasterrcnn-小象cv-code
    C4-ResNet-TF-小象cv-code
  • 原文地址:https://www.cnblogs.com/EcliWalker/p/8324984.html
Copyright © 2011-2022 走看看