现在的位置: 首页 > 综合 > 正文

hdu 1051 Wooden Sticks【贪心】

2012年08月24日 ⁄ 综合 ⁄ 共 3233字 ⁄ 字号 评论关闭

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;
}

抱歉!评论已关闭.