3232 accelerator(二分逼近)
二分法的總體思路就是,(1)以二分的方法確定乙個值,假定這個值就是答案,(2)判斷這個值是大還是小,並在相應半區重新估值,再判斷;(3)以半區區間的左邊界left不再比右邊界小為結束條件。(有一點貪心的思路在裡面,這個最短的時間內,顯然所有加速器都在被使用,這樣才會時間最短)(這就要求,要事先知道判斷方法:乙個值是偏大還是偏小,如果知道了判斷方法,就能逼近最優解:先隨便找乙個解,然後判斷,然後二分再判斷)
題意:給出n輛賽車距離終點的距離,每秒鐘會前進1公尺,現在給出m個可以加速k的加速器,每次每輛車只能使用一次加速器,下乙個時間點加速器可以重複使用。問所有賽車到達終點的最短時間。
輸入:(1)t,小麵有t個case;
(2)n,有n個賽車;
(3)n個數,表示賽車到終點的距離;
(4)m,k,表示有m個加速器,及加速度;
輸出:t行數:每個案例全部賽車到達終點的距離。
與3104題意相同,只是由乙個吹風機變成m個吹風機。小雨3104超時,看這次能否重新理解和完成。
思路:(一)簡單的貪心思路,如吹風機每一分鐘都選擇最濕的衣服烘乾,加速也在每分鐘都選擇距離最遠的m個賽車加速就可以了。這就意味著,每一分鐘要對賽車到終點的距離排序。但是看資料,肯定不能去模擬每一分鐘(對每一分鐘進行排序會超時,如同小雨做3104時的情況)。既然不能模擬每一分鐘,也就意味著不需要給最大的加速。
(二)二分逼近
本題步驟:
1、要找所有車全部通過終點的最短時間,顯然,這個時間在1和最遠距離max之間。於是,通過二分法,假定mid就是這個最短時間,然後去判斷(check函式)這個時間是大了還是小了,再在某一半區重新二分得到mid,一直到l=r(區間最小),得到正確答案。
2、如何判斷,即寫乙個函式:int check(int acc_time),在主程式中呼叫是為check(mid),也就是把mid作為加速的時間(就是加幾次速),判斷大了還是小了
(1)函式目的是,判斷給定的acc_time作為賽車都過終點的最短時間,是大了還是小了。
(2)顯然,要對每台車進行分析
(3)如果本車離終點的距離小於等於mid,顯然,它不用加速,自己就走過去了,於是進入下一台車的判斷。
(4)否則,意味著這台車需要加速,於是要計算這台賽車需要加速的次數times。本題關鍵就在於:對本台車的加速次數如何計算?
本台車,距離終點a[i],可以這麼看,所有車到終點的預設時間是mid,在這mid分鐘內,設加速times次,那麼a[i] =times×k + (mid –times),前乙個是加速走的距離,後面是自己走的距離,於是,times = (a[i] – mid)/(k-1),注意向上取整。
(5)判斷:
mid偏小有兩個判斷,一是看單台車,二是看總加速次數:
如果本車的times大於mid(也就是總體上給的賽車只能加速mid次),就意味著,這台車要到終點,需要加速的次數比給的mid要大,所以,mid預估小了,返回false。一旦發現有一輛車是這種情況,就不再往下check了,返回false,之後在主程式中調大m的值;
還有一種估值小的可能,就是所有車的總加速次數,在迴圈中累加每台車的加速次數,如果大於mid*m(即有m臺加速器,就是假定到終點的時間為mid,那麼,所有車可以加速的總次數是m×mid),也說明mid估計小了。所有車的加速總次數用累加,就是把本台車的加速次數tmp累加上去。
偏大的判斷:
在對所有車都分析一次後,如果沒有返回false,就說明mid的估值不小(可能大了),返回true。然後,在主程式中縮小估值,再判斷。
至此,這道題就分析完成了。
ac細節:
ceil函式加上 1.0*,從整數變成浮點數乘法;times = ceil(1.0 * (a[i] - mid) / (k - 1));
long long total= (long long) m * acc_time; //一定要注意!int溢位是隨時都可能發生的,所以先強制轉換,儲存起來
二分法迴圈條件用小於等於while(left <= right)
處理k=1的特殊情況,如果k=1,直接輸出最大值max
超時處理:用scanf\printf替代cin\cout;
wrong answer:二分輸出left而不是mid;需要試驗一下,一般mid也對。
3104與3232相似:加速器台數m只在函式check(mid)中判斷總加速次數是否超過m×acc_time時用到,在只有乙個加速器(烘乾機)時,這個條件可以去掉,然後,就可以成為3104的解決方案。
3104題意:有n件剛洗的衣服,每件衣服給定乙個含水量。有乙個烘乾機,每分鐘可以選一件衣服去烘,每分鐘可以烘掉k的水量。每件衣服每分鐘可以自動蒸發掉1的水量,用烘乾機時不蒸發。問最少需要多少時間能烘乾所有的衣服。
輸入:第一行:n,表示n件衣服;
第二行:n個數,表示n件衣服的含水量;
第三行:k,表示烘乾機每分鐘去掉的水量。
輸出:多少分鐘把n件衣服烘乾。
poj 3104 二分想法
給你n個數表示含水量,給你乙個k表示每分鐘洗衣機能脫水k滴 每分鐘沒有在洗衣機的衣服自動脫水一滴,求把全部水託幹最小時間,怎麼都沒想到居然是二分 好吧,二分列舉最小時間mid,然後求實際所需時間再 經行判斷,如果列舉時間為mid,對每件衣服num i 如果num i 小於mid 很顯然直接自然幹最好...
poj 3104 二分答案
題意 n件濕度為num的衣服,每秒鐘自己可以蒸發掉1個濕度。然而如果使用了暖爐,每秒可以燒掉k個濕度,但不計算蒸發了。現在問這麼多的衣服,怎麼燒事件最短。解析 二分答案咯。include include include include include include include include ...
POJ 3104 Drying 二分 貪心
題目大意 有n件溼的衣服,每件衣服都有相應的濕度,每分鐘每件衣服的濕度減1 除了在烘乾機裡的衣服 現在有乙個烘乾機,烘乾機一分鐘可以讓一件衣服的濕度降低k,問至少要花多少分鐘才能使每件衣服的濕度為0 解題思路 貪心的話,每分鐘都要使用到烘乾機。列舉時間,如果濕度小於等於時間的話,就不用考慮了,在列舉...