ACM题解——贪心专题——木头加工
ACM題解——貪心之木頭加工
題目描述
There is a pile of n wooden sticks. The length and weight of each stick are known in advance. The sticks are to be processed by a woodworking machine in one by one fashion. It needs some time, called setup time, for the machine to prepare processing a stick. The setup times are associated with cleaning operations and changing tools and shapes in the machine. The setup times of the woodworking machine are given as follows:
(a) The setup time for the first wooden stick is 1 minute.
(b) Right after processing a stick of length l and weight w , the machine will need no setup time for a stick of length l' and weight w' if l<=l' and w<=w'. Otherwise, it will need 1 minute for setup.
You are to find the minimum setup time to process a given pile of n wooden sticks. For example, if you have five sticks whose pairs of length and weight are (4,9), (5,2), (2,1), (3,5), and (1,4), then the minimum setup time should be 2 minutes since there is a sequence of pairs (1,4), (3,5), (4,9), (2,1), (5,2).
?
Input
The input consists of T test cases. The number of test cases (T) is given in the first line of the input file. Each test case consists of two lines: The first line has an integer n , 1<=n<=5000, that represents the number of wooden sticks in the test case, and the second line contains n 2 positive integers l1, w1, l2, w2, ..., ln, wn, each of magnitude at most 10000 , where li and wi are the length and weight of the i th wooden stick, respectively. The 2n integers are delimited by one or more spaces.
?
Output
The output should contain the minimum setup time in minutes, one per line.
?
Sample Input
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 1Sample Output
2 1 3題目大意
給n根木頭,加工第一根1min,當后面的木頭長寬都大等前面一根時,加工時間為0min,否則加工時間為1min;分別給出這n根木頭長和寬,求加工所需的最短時間。
?
題解
開始我的思路是木頭存放在一個結構體中,結構體按照長寬都最小的排到最前面,后面只能排長寬都比前一個大的,直到排完之后然后排長寬有交錯(長寬有一個大于前面,有一個小于前面),再次進行同樣的排序,然后從前往后找,找到交錯的位置就時間加1,但是結構體排序無法實現這樣的排序方式就是無法將交錯的木頭放到最后。因此需要手動實現:
首先現將結構體按長(或寬)從小大到大排序,結構體中除了存放這根木頭的長和寬,還要存放訪問標記,初始化為0(未訪問);然后用for循環從前往后找,找到第一個標記為0的點,把標記改為已訪問,時間計數器加一,并設置當前長curr_L和當前寬curr_W,從這個點開始,凡是后面木頭訪問標記為0且長寬都大于當前長curr_L和當前寬curr_W的,就把其訪問標記設為已訪問,然后當前長curr_L和當前寬curr_W更新為這個木頭的長和寬,直到所有木頭都遍歷;一圈掃完之后就是完成了以第一個最小木頭打頭的雙遞增排列。
然后跳出內層循環,再次進入外層循環,繼續尋找當前第一個訪問標記為0的木頭,其實就是那些沒有被加入上一個雙遞增排列的木頭,開始第二個雙遞增排列,以這個木頭為頭,從其后面開始再次內循環,重復上面的操作即可。直到外層循環找不到標記點為0的木頭就結束,輸出計數器的值即為答案。
代碼
#include<iostream> #include<algorithm> using namespace std; struct wood {int len;int wid;int add; }; bool cmp2(wood x,wood y) {if(x.len==y.len)return x.wid<y.wid;elsereturn x.len<y.len; }int main() {int t=0;cin>>t; //t個casefor(int i=0;i<t;i++){int n=0;cin>>n;wood *mt=new wood[n];que *Q=new que[n];bool *book=new bool[n]; //可以把訪問標記直接放到結構體里面for(int j=0;j<n;j++){cin>>mt[j].len>>mt[j].wid;book[j]=0;}sort(mt,mt+n,cmp2); int cur_l=0,cur_w=0,coun=0;//當前長、寬和時間計數器for(int k=0;k<n;k++){if(book[k]==0){cur_l=mt[k].len;cur_w=mt[k].wid;book[k]=1;coun++;for(int j=k+1;j<n;j++){if(book[j]==0 && mt[j].len>=cur_l && mt[j].wid>=cur_w){cur_l=mt[j].len;cur_w=mt[j].wid;book[j]=1;}}}}cout<<coun<<endl;}return 0; }?
總結
以上是生活随笔為你收集整理的ACM题解——贪心专题——木头加工的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Alternate Realities大
- 下一篇: GCC——C compiler