题意:
有 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 }
方法二:
分组,只记录每组第一个,标记为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 ", cnt); 50 } 51 return 0; 52 }