zoukankan      html  css  js  c++  java
  • hdu 1051 Wooden Sticks【贪心】

    Wooden Sticks

     

    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

    题意:给你 N 个木棍,每根木棍都有一个长度 l 和一定重量 w 。

          机器每对一根进行操作需要一分钟的时间 ,但是如果当前进行操作的木棍的长度和重量都不小于前一根,

          那么这根木棍就不需要加时间。

    算法:贪心 + 标记

    思路:先按照长度由小到大排序,如果长度一样,则按照重量由小到大排序。

          依次操作每根木棍,同时标记已经操作。

          操作当前木棍时,同时检查是否可以使它后面的木棍直接操作而且不用加时间,如果可以,则直接操作并且记

          已操作。

    F Accepted 328 KB 15 ms C++ 1004 B 2013-04-20 19:58:06
    Accepted 1051 15MS 328K 1059 B C++ free斩

    #include<stdio.h>
    #include<algorithm>
    using namespace std;
    
    const int maxn = 10000+10;
    
    struct Node{
        int l;
        int w;
        bool vis; //重要
    }node[maxn];
    
    bool cmp(Node a, Node b)
    {
        if(a.l != b.l) return a.l < b.l; //先按照长度排序
        else return a.w < b.w; //再按照重量排序
    }
    
    
    int main()
    {
        int T;
        int n;
        scanf("%d", &T);
        while(T--)
        {
            scanf("%d", &n);
            for(int i = 0; i < n; i++)
            {
                scanf("%d%d", &node[i].l, &node[i].w);
                node[i].vis = false; //每根木棍均未操作
            }
            sort(node, node+n, cmp);
    
            int ans = 0;
            for(int i = 0; i < n; i++)
            {
                if(node[i].vis) continue; //如果已经操作过,直接跳出
    
                ans++; // 前面没有可以使它直接操作的木棍
                node[i].vis = true; 
                int weight = node[i].w; //由于长度已排序,所以只用记录重量
                for(int j = i+1; j < n; j++)
                {
                    if(!node[j].vis && node[j].w >= weight) //如果满足不用+时间
                    {
                        node[j].vis = true; //直接操作
                        weight = node[j].w; //同时更新下一根可以操作的 w 界限
                    }
                }
            }
            printf("%d\n", ans);
        }
        return 0;
    }
    


    误区:1.按照题目中说的序列排序,遇到 l 或者 w 比前面小的,则时间 +1,感觉思路应该是对的,估计是第二排         序时换来换去,哪儿错了吧。

          2.按照并查集,把满足情况的放到一个连通分量中,再求有几个根。

            想法很美好,错的不听紧!!!

    下面贴个误区一的代码,希望路过的,有想法的给我改下。。。。

    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    
    struct Node
    {
        int w,l;
    }node[5005];
    
    bool cmp(Node a, Node b)
    {
        if(a.w != b.w) return a.w < b.w;
        else return a.l < b.l;
    }
    
    int main()
    {
        int T;
        int n;
        scanf("%d", &T);
        {
            while(T--)
            {
                scanf("%d", &n);
                for(int i = 0; i < n; i++)
                {
                    scanf("%d%d", &node[i].w, &node[i].l);
                }
                sort(node, node+n, cmp);
     
                Node now = node[0];
                for(int i = 1; i < n; i++)
                {
                    if(node[i].l < now.l)
                    {
                        for(int j = i+1; j < n; j++)
                        {
                            if(node[j].l < now.l && node[j].l >= node[j-1].l)
                            {
                                now = node[j-1]; break;
                            }
                            else
                            {
                                Node temp = node[j-1];
                                node[j-1] = node[j];
                                node[j] = temp;
                            }
                        }
                    }
                }
                /*for(int i = 0; i < n; i++)
                {
                    printf("%d %d\n", node[i].w, node[i].l);
                }*/
                int ans = 1;
                for(int i = 1; i < n; i++)
                {
                    if(node[i].w < node[i-1].w) ans++;
                    else if(node[i].l < node[i-1].l) ans++;
                }
                printf("%d\n", ans);
            }
        }
        return 0;
    }


  • 相关阅读:
    php aes128加密
    redis应用场景
    Yii2开发小技巧
    yii2开启事务
    yii2验证密码->手机号码短信发送>手机短信发送频繁问题
    yii2 rules验证规则,ajax验证手机号码是否唯一
    随笔20170415
    v1版本
    数的划分
    单词接龙
  • 原文地址:https://www.cnblogs.com/freezhan/p/3219070.html
Copyright © 2011-2022 走看看