木棍
时间限制: 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)的序列。
的安装时间如下: (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就加一分钟时间,直到所有的木棍都考虑结束。