Wooden Sticks(POJ1065)(貪心)

木棍
時間限制: 1000MS   內存限制: 10000K
提交總數: 27336   接受: 11857

描述ios

有一堆木棍。每根杆的長度和重量是預先已知的。這些木棍將由木工機器逐一加工。它須要一些時間,稱爲設置時間,以便機器準備處理棒。設置時間與清潔操做以及更換機器中的工具和形狀相關聯。木工機械
的安裝時間以下: (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個整數由一個或多個空格分隔。

產量測試

輸出應包含最小設置時間(以分鐘爲單位),每行一個。

樣本輸入spa

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 

樣本輸出code

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就加一分鐘時間,直到全部的木棍都考慮結束。
相關文章
相關標籤/搜索