貪心策略 渡河 river

2022-05-30 18:15:20 字數 2796 閱讀 2102

「假舟楫者,非能水也,而絕江河。

」這句話說的是,借助渡船的人,不是會游水,卻能橫渡江河。

會游水的人反而不一定能順利地橫渡江河。由於江面風浪很大,他們必須潛泳渡河。這就必須用到氧氣瓶。氧氣瓶當然是出題人買的,而出題人沒錢,所以只買了乙個。這種氧氣瓶有兩個輸出氧氣的管道,最多可供兩個人同時過河;其中的氧氣是無限的。

顯然每次應該有兩個人過河,再派對岸的乙個人把氧氣瓶送回來。需要注意的是,已經橫渡到對岸的所有隊員都可以送回氧氣瓶。

現在給定你每個人渡河所需的時間,要你求出,按照以上方案把所有人送到對岸,所需的最短時間。兩個人一起過河的時候,所需的時間等於慢的人所用時間。

【輸入檔案】第一行,乙個正整數n。

其餘n個正整數,在第

2行,相鄰兩個整數之間用乙個空格隔開。

【輸出檔案】一行1個整數,表示所用的最短時間。

【樣例輸入】

1 3 4

【樣例輸出】8

【資料規模和約定】

對於20%的資料,

n<=10

對於100%的資料,檔案中的所有整數

<=1000

【題解】

本題非常的奇怪,一拿到題目首先想到的貪心方法就是

以1號做中轉,每次由

1號送乙個人到對岸,再從對岸送回氧氣瓶。

典型的例子是這組資料: 1 2 9 9

最優的方法是1與

2號過去,

1號回來,3與

4號過去,

2號回來,1與

2號過去。這個方案花費是

16。如果按照原先的方案,花費是22。

但是,絕對的存在反例!

典型的例子是這組資料:1 9 9 9

原先的方案最佳(29),新方案反而差(

37)。

經過仔細觀察,我們發現乙個事實,對岸的人只有兩個過河時間最小的人有意義

這裡的意義實質上是由兩個過河時間最小的人來決定最優解。

假定現在我們現在需要挨個過河,有2+2=4個人;

下標 分別是1 2 i-1 i

有兩種方法:

①1號自己把兩個人帶過去。

1 i(1和i共用氧氣筒) 1(1送還氧氣筒) 1 i-1(1把i-1送到對岸) 1(再回來準備下乙個)

用時為下標為 i 1 i-1 1的時間之和

②1號回來,兩個人一起去對岸,

2號回來以後再跟

1號一起回去。

1 2(1 2一起去對岸) 1(1回來送氧氣筒) i i-1(i和i-1自生自滅一起渡河) 2(2回來和1匯合準備下一次)

用時為下標為 2 1 i 2的時間之和

所以記t1=a[1]+a[2]+a[i-1]+a[i];t2=a[2]+a[1]+a[i]+a[2];

sum=sum+min(t1,t2);

接下來分奇偶討論!

當渡河人數為偶數時,偶數-2=偶數

不妨設n恰好為4時,只需要渡河一次,

按照上訴2種方法,①可行,②扯淡,此時②必然會回到本岸,所以還要回去,sum=sum+a[2]

當渡河人數為奇數時,奇數-2=奇數

當n恰好為3時,就是1 2 3的渡河方法,最快的 1 3(1 3去) 1(回來送氧氣筒) 1 2(1 2去)

時間是 3 1 2= a[1]+a[2]+a[3] sum=sum+a[1]+a[2]+a[3];

所以程式就非常簡單:

var

t1,t2,n,sum,i:longint;

a:array[1..1000]of

longint;

procedure

qsort(l,r:longint);

vart,i,j,mid:longint;

begin

i:=l; j:=r;

mid:=a[(l+r)div2];

while ido

begin

while a[i]do

inc(i);

while a[j]>mid do

dec(j);

if i<=j then

begin

t:=a[i]; a[i]:=a[j]; a[j]:=t;

inc(i);dec(j);

end;end

;if lthen

qsort(l,j);

if r>i then

qsort(i,r);

end;

begin

assign(input,

'river.in');

assign(output,

'river.out');

reset(input);

rewrite(output);

readln(n);

for i:=1

to n do

read(a[i]);

qsort(

1,n);

if n mod

2=1then sum:=a[1]+a[2]+a[3]

else sum:=a[2

]; i:=n;

while i>3

dobegin

t1:=a[2]+a[1]+a[i]+a[2

]; t2:=a[i]+a[1]+a[i-1]+a[1

];

if t1>t2 then t1:=t2;

sum:=sum+t1;

i:=i-2;

end;

writeln(sum);

close(input);

close(output);

end.

快速渡河(貪心演算法)

問題描述 有n的人需要過河,但只有乙隻船,且一次只能載兩個人。每個人都有乙個渡河的速度,過河的速度取決於速度最慢的那乙個,求所有人過完河的最短時間。輸入乙個n,表示有n個人。接著輸入n個整數表示每個人過河需要的時間。例如 4 1 2 5 10 輸出 17 思路 有兩種可以快速過河的策略,一是由最快的...

演算法策略 貪心

目錄 貪心 greedy 練習1 最優裝載問題 加勒比海盜 問題 思路 實現 練習2 零錢兌換 問題 思路 實現 貪心策略中存在的問題 注意 練習3 0 1揹包 問題 思路例項分析 實現 貪心策略,也稱為貪婪策略,每一步都採取當前狀態下最優的選擇 區域性最優解 從而希望推導出全域性最優解 貪心的應用...

貪心策略 專案利潤

題目描述 輸入 cost 每個專案的花費 profits 每個專案的利潤 純利潤 k 最多能做k個專案 w 表示初始資金 輸出 最後獲得的最大錢數 說明 一次只能做乙個專案,且做完乙個之後馬上就能獲得收益,可以支援做下乙個專案 貪心策略 當資金有限時如何選擇那個專案使得掙的錢最多 演算法思想 1 將...