hdu 1051 Wooden Sticks(贪心)

题目链接:点击打开链接

Wooden Sticks

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


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

题意:有n根木头,一台机器,切割第一根木头时要花费1分钟,如果当前切割的木头长度和宽度小于或等于前一根,那么不需要花费时间,否则花费一分钟

问最少花费几分钟?

思路:算是动态规划最长单调子序列变形吧,不过有点不同的是求的不是最长的序列,而是最少可以是几个序列。于是我们想到了贪心,贪心策略是:

1:把所有木头按照长度从小到大排序(当然按照宽度也可以),然后遍历一遍所有木头

2:每次遍历到某一根木头,就去查找一遍此木头前面的木头(也就是长度小于等于当前木头的木头)是否有宽度小于等于当前木头宽度的木头,如果有多根,就在这多根木头里面取宽度最大的那一根(这道题里宽度越大越没价值,宽度越小,后面的木头更有可能可以不花时间进行加工)

3:注意同一根木头只能作为一根木头的前缀,也就是说如果有三根木头是(2,2),(3,4),(4,3) 那么此时答案应该是2而不是1,虽然(3,4)和(4,3)都可以以(2,2)作为前缀,但是机器切割木头的时候比较的是前一根木头,而不是前面切割过的所有木头。 而(3,4)是不能作为(4,3)前缀的,反之(4,3)也是不能作为(3,4)前缀的。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 5010
struct Wood
{
    int l,w;
}wood[N];
bool cmp(Wood a,Wood b)
{
    if(a.l==b.l)
        return a.w<b.w;
    return a.l<b.l;
}
int main()
{
    int T,n;
    int dp[N],vis[N];
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(int i=0;i<n;i++)
            {
                scanf("%d %d",&wood[i].l,&wood[i].w);
                dp[i]=1;
                vis[i]=0;
            }
        sort(wood,wood+n,cmp);
        int num=1,v;
        for(int i=1;i<n;i++)
        {
            v=-1;
            for(int j=i-1;j>=0;j--)
            {
                if(wood[i].w>=wood[j].w&&vis[j]==0)
                   {
                       if(v==-1||wood[j].w>wood[v].w)
                            {
                                dp[i]=dp[j]+1;
                                v=j;
                            }
                   }
            }
            if(dp[i]==1)
                num++;
            vis[v]=1;
        }
        printf("%d\n",num);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值