题意:

有 n 根木棒,长度和质量都已经知道,需要一个机器一根一根地处理这些木棒。

该机器在加工过程中需要一定的准备时间,是用于清洗机器,调整工具和模板的。

机器需要的准备时间如下:

1.第一根需要1min的准备时间;              

2.在加工了一根长为 l ,重为 w 的木棒后,接着加工一根长为 l’(l <= l’),重为 w’

(w <= w’)的木棒是不需要任何准备时间的,否则需要1min时间。

求加工 n 根木棒所用的最少时间。例如现有长和重分别为(4,9),(5,2),(2,1),(3,5)和(1,4)

的5根木棒,那么所需的最少时间为2min,顺序为(1,4),(3,5),(4,9),(2,1),(5,2);

分析:

属于资源调度问题,贪心算法能获得很好的效率。

但仅用贪心还是不够的,排序后还要用动态规划

方法一:

排序后求上升子序列的最少组数,这个组数即最少时间。

代码如下:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 struct mu
 7 {
 8     int L,W;
 9 } m[5005];
10 bool cmp(mu a, mu b)
11 {
12     if(a.L == b.L)      //优先按长度排序,相等时按重量
13         return a.W < b.W;
14     else
15         return a.L < b.L;
16 }
17 int main()
18 {
19     int t;
20     int b[5005];  //记录第 i 个木棒的分组序号
21     cin >>t;
22     while(t--)
23     {
24         memset(b, 0, sizeof(b));
25         int n;
26         cin >>n;
27         for(int i = 0; i < n; i ++)
28             scanf("%d%d", &m[i].L, &m[i].W);
29         sort(m, m + n, cmp);
30         b[0] = 1;  //第一个分为第一组
31         for(int i = 1; i < n; i ++)  //依次为后面的木棒分组
32         {
33             int k = 0;
34             for(int j = 0; j < i; j ++)  //在当前木棒前面的木棒中找到比它沉且组数为最大的
35                 if(m[i].W < m[j].W && k < b[j])
36                     k = b[j];
37             b[i] = k + 1;  //当前木棒分为第 k + 1 组
38         }
39         int ma = 0;
40         for(int i = 0; i < n; i ++)  //最大组数即最少时间
41             if(b[i] > ma)
42                 ma = b[i];
43         cout <<ma <<endl;
44     }
45     return 0;
46 }
View Code

方法二:

分组,只记录每组第一个,标记为0,其余的标记为1.

代码如下:

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 struct mu
 7 {
 8     int l, w;
 9 } m[5005];
10 bool cmp(mu a, mu b)
11 {
12     if(a.l == b.l)
13         return a.w < b.w;
14     else
15         return a.l < b.l;
16 }
17 int main()
18 {
19     int t, n;
20     int b[5005];
21     cin >>t;
22     while(t --)
23     {
24         memset(b, 0, sizeof(b));
25         scanf("%d", &n);
26         for(int i = 0; i < n; i ++)
27             scanf("%d%d", &m[i].l, &m[i].w);
28         sort(m, m + n, cmp);
29         for(int i = 0; i < n; i ++)
30         {
31             if(b[i] == 1)
32                 continue;  //已分组,看下一个
33             int k = m[i].w;  //本组第一个
34             for(int j = i + 1; j < n; j ++)
35             {
36                 if(b[j] == 1)
37                     continue;
38                 if(m[j].w >= k) //后面升序的都归为本组
39                 {
40                     k = m[j].w;
41                     b[j] = 1;
42                 }
43             }
44         }
45         int cnt = 0;
46         for(int i = 0; i < n; i ++)
47             if(b[i] == 0)
48                 cnt ++;
49         printf("%d\n", cnt);
50     }
51     return 0;
52 }
View Code

 

        

posted on 2014-07-22 14:12  Acmer_侯贺帅  阅读(155)  评论(0编辑  收藏  举报