[問題描述]
晚會上大家在玩一款“暴力摩托”的遊戲,它擁有非常逼真的畫面和音響效果,如疾馳而過的汽車呼嘯聲,>機車的引擎聲和轉彎時輪胎與地面摩擦而產生的聲音。而且它在遊戲中加入了對抗成份,比賽中你可以使用拳、腳去幹擾對方,使其落後於你,是不是很卑鄙啊? 遊戲中千萬不能手下留情,因為對手會主動攻擊你。如果遇到開>機車的警察,雖然也可以對他踢上一腳,但可得小心點呀,萬一被他們捉住了,那就 GAME OVER 啦!當然了,車子總是要加油的咯,已知賽道長S公裡(S≤10000整數,且為10的倍數),賽車的油耗Q=1,即1公裡路耗1個單位的油。Q不變,賽車的油箱為無窮大,同時在沿途的任何地方都可以加油。 約定,每次加油的數量為整數,且為10的倍數,賽車的速度與賽車加油後的總油量有關。其關係如下表列出:同時,汽車每加油一次需要耗費T分鐘(T<=100不論加油多少,開始時的加油不計時間)當S,T給出之後,選擇一個最優的加油方案。使汽車以最少時間跑完全程。例如:當S=40,T=6(分鐘),加油的方案有許多種,列出一些:1)起點加油40,用時40/75≈0.53小時2)起點加油20,中途加20,用時20/90+20/90+6/60(化為小時)≈ 0.54 小時 [輸入檔案] 一行,為兩個整數S、T。 [輸出檔案] 輸出一行,為最少用時(保留二位小數) [輸入範例] 40 6 [輸出範例]
解題思路
DP。
我們發現前面怎麼走的與後面無關,那麼我們可以用a【i】表示行駛i*10公裡時所用的最短時間。分別搜尋每個階段a【i】的最小用時,那麼a【n】即答案 代碼
var s,i,j,t:longint; a:array[1..1000]of real; m,min:real;begin assign(input,'car.in'); assign(output,'car.out'); reset(input); rewrite(output); readln(s,t); for i:=1 to s div 10 do //每10公裡為一個階段 begin case i of 1:min:=10/100; //計算從0開始到i*10距離如果不加油,可達的最小時間,以此為當前階段a【i】的初始值min,當前階段將i*10看做終點 2:min:=20/90; 3:min:=30/80; 4:min:=40/75; else min:=(i*10)/70; end; for j:=1 to i-1 do //枚舉每個可能加油的地方,測試如果在這裡加1次油的話那以此向後到終點能否使時間減少,即尋找最優方案 begin case (i-j) of //(i-j)*10即從當前j*10到當前階段終點i*10的距離 1:m:=10/100; 2:m:=20/90; 3:m:=30/80; 4:m:=40/75; else m:=((i-j)*10)/70; end; m:=m+t/60; if m+a[j]<min then min:=m+a[j]; // 比較,看 能否使當前階段a【i】的總時間減少 end; a[i]:=min; end; write(a[s div 10]:0:2); close(input); close(output);end.哪裡都找不到測試OJ。。。。。。。。so也不知道A不A