POJ1065(Wooden Sticks)--贪心

木棍
时间限制: 1000MS   内存限制: 10000K
提交总数: 27336   接受: 11857

描述

有一堆木棍。每根杆的长度和重量是预先已知的。这些木棍将由木工机器逐一加工。它需要一些时间,称为设置时间,以便机器准备处理棒。设置时间与清洁操作以及更换机器中的工具和形状相关联。木工机械
的安装时间如下: (a)第一根木棒的安装时间为1分钟。 
(b)在加工长度为l且重量为w的棒之后,如果l <= 1'且w <= w',则机器将不需要设置长度l'和重量w'的设定时间。否则,需要1分钟进行设置。 
你要找到处理一堆n根木棍的最短安装时间。例如,如果您有五根长度和重量对分别为(9,4),(2,5),(1,2),(5,3)和(4,1),那么最小设置时间应该是2分钟,因为存在一对(4,1),(5,3),(9,4),(1,2),(2,5)的序列。

输入

输入由T个测试用例组成。测试用例(T)的数量在输入文件的第一行中给出。每个测试用例由两行组成:第一行有一个整数n,1 <= n <= 5000,表示测试用例中木棒的数量,第二行包含2n个正整数l1,w1,l2, w2,...,ln,wn,每个幅度最多10000,其中li和wi分别是第i个木棍的长度和重量。2n个整数由一个或多个空格分隔。

产量

输出应包含最小设置时间(以分钟为单位),每行一个。

样本输入

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 

样本输出

2
1
3
分析:找出最佳加工顺序即可求出最优解,而且这个题目类似于最大兼容活动子集,所以我将L和W看成活动的开始和结束时间。只需要将他们按规则排好序,两层for就可以得出最少分钟数
 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<vector>
 6 #include<stack>
 7 #include<map>
 8 #include<set>
 9 #include<list>
10 #include<queue>
11 #include<string>
12 #include<algorithm>
13 #include<iomanip>
14 using namespace std;
15 
16 #define MAX 10005
17 int t;
18 int n;
19 
20 struct woodensticks
21 {
22     int Begin;
23     int End;
24     bool operator < (const woodensticks & s)const
25     {
26         if(End == s.End)//W相等
27         {
28             return Begin <= s.Begin;//按L递增排序
29         }
30         else
31         {
32             return End <= s.End;//否则W递增排序
33         }
34     }
35 };
36 
37 woodensticks arr[MAX];
38 int vis[MAX]; 
39 
40 int main()
41 {
42     cin>>t;
43     while(t --)
44     {
45         int Count = 1 ;
46         memset(arr,0,sizeof(arr));
47         memset(vis,0,sizeof(vis));
48         cin>>n;
49         for(int i = 1;i <= n; i++)
50         {
51             cin>>arr[i].Begin>>arr[i].End;
52         }
53         sort(arr + 1,arr + n + 1); 
54         for(int i = 1; i <= n;i ++)
55         {
56             if(vis[i] == 0)//当前木棍未考虑
57              {
58                 vis[i] = 1;
59                 int prebeg = arr[i].Begin;
60                 int preend = arr[i].End;//记录其W和L
61                 for(int j = i + 1; j <= n;j++)//依次比较其后面的
62                 {
63                     if(arr[j].Begin >= prebeg && arr[j].End >= preend && vis[j]== 0)//找出最近的L<=L',W<=W'
64                     {
65                         vis[j] = 1;//标记
66                         preend = arr[j].End;
67                         prebeg = arr[j].Begin;//更新并重复,直到循环结束 回到第一层for未考虑的 继续贪心选择
68                     }
69                 }
70                 Count ++;
71             }
72         }
73         cout<<Count-1<<endl;//多加一次,减掉1
74     }    
75     return 0;
76 }//Accepted    840K    79MS
因为已经按规则排好了序,所以在第二个for循环内总能挑出在1分钟内加工完的所有木棍,每次进入第二层for就加一分钟时间,直到所有的木棍都考虑结束。
原文地址:https://www.cnblogs.com/ygsworld/p/10982284.html