Topic Links:
Http://codeforces.com/problemset/problem/747/D
Main topic:
The next n days there is a daily temperature, if the temperature is negative for one day, you must use winter tyres, and the temperature is not negative, you can use both winter tyres, but also the use of summer tyres. In the beginning, the car was loaded with a summer tyre, and if the type of tyre used for two consecutive days was different, a tyre change was required. The total number of days required to use winter tyres should not exceed K, asking for the minimum number of tyres to be changed. (Note: The car can be installed either as a winter tyre or as a summer tyre after the end of the N days.)
Problem Solving Ideas:
At first think of dp+ scrolling array. However, the complexity of the time is too high, looked tutorial found can be greedy. Specifically, it is:
1. When the sum of the number of days with a negative temperature is greater than k, there is no solution.
2. Otherwise, K minus the number of days of negative temperature. And the number of all successive sections with negative temperature is CNT, at which time the number of changes X is cnt*2.
3. Find all successive sections with a non-negative temperature and push the length of such segments into a small top heap. Do not consider persisting to the non-negative section of Nth day (if any), do not put such a section in the heap (then judge this special case). It is also not necessary to consider a non-negative section that starts on the 1th day until the first negative section, because the car is on a summer tire, and such a section does not affect the final result.
4. When the heap is not empty and k is greater than or equal to the heap top element, pop out the top element of the heap and subtract k from the top element of the heap, and make X-= 2. (equivalent to greedy to merge non-negative segments)
5. Consider special circumstances: if there is a non-negative segment and this section lasts to the Nth day, and at this time K is greater than or equal to the length of this segment, then it can be x--(equivalent to the last non-return of the summer tyres, eliminating a change of the tyre operation), or the last negative section lasts to the nth day, This also eliminates the need to switch back to the summer tyres and x--。 In short, whether the last segment that lasts to n days is a negative or non-negative segment, X--。 This gives the final answer.
In fact, the idea is not very difficult to think, but to realize the need to pay attention to some details.
The code is not very beautiful:
1#include <iostream>2#include <cstdio>3#include <queue>4#include <functional>5#include <vector>6 using namespacestd;7 8 inta[200005], N, K;9 intFind_non_negtive_start (intPOS)Ten { One for(inti = pos; I < n; i++) A { - if(A[i] >=0) - returni; the } - return-1; - } - intFind_non_negtive_end (intPOS) + { - for(inti = pos; I < n; i++) + { A if(A[i] <0) at returnI1; - } - return-1; - } - intFind_negtive_start (intPOS) - { in for(inti = pos; I < n; i++) - { to if(A[i] <0) + returni; - } the return-1; * } $ intFind_negtive_end (intPOS)Panax Notoginseng { - for(inti = pos; I < n; i++) the { + if(A[i] >=0) A returnI1; the } + return-1; - } $ intMain () $ { -priority_queue<int, vector<int, greater<int> >Q; -CIN >> N >>K; the intCNT =0, cnt_negtive =0; - intStart =-1, Begin =-1;Wuyi for(inti =0; I < n; i++) the { -scanf"%d", &a[i]); Wu if(A[i] <0) - { Aboutcnt++; $ if(Begin = =-1) -Begin =i; - } - Else A { + if(Begin! =-1&& start = =-1) theStart =i; - } $ } the if(CNT >k) the { thecout <<"-1"<<Endl; the return 0; - } in if(CNT = =0) the { thecout <<"0"<<Endl; About return 0; the } the if(Start = =-1) the { +cout <<"1"<<Endl; - return 0; the }Bayi if(Begin = =-1) the { thecout <<"0"<<Endl; - return 0; - } theCnt_negtive =CNT; theCNT =0; the while(1) the { - intpos = find_negtive_end (begin +1); the if(pos = =-1) the { thecnt++;94 Break; the } thecnt++; theBegin = Find_negtive_start (pos +1);98 if(Begin = =-1) About Break; - }101CNT *=2;102 intres =-1;103 while(1)104 { the intpos = find_non_negtive_end (start +1);106 if(pos = =-1)107 {108res = n-start;109 Break; the }111Q.push (Pos-start +1); theStart = Find_non_negtive_start (pos +1);113 if(Start = =-1) the { the Break; the }117 }118K-=cnt_negtive;119 while(!q.empty ()) - {121 if(k >=q.top ())122 {123K-=q.top ();124 Q.pop (); theCNT-=2;126 }127 Else - {129 Break; the }131 } the if(k >=Res)133 {134cnt--;135 }136cout << CNT <<Endl;137 return 0;138}
cf747d Winter is Coming