51nod 獨木舟問題

2021-07-09 21:58:28 字數 1667 閱讀 6616

n個人,已知每個人體重,獨木舟承重固定,每只獨木舟最多坐兩個人,可以坐乙個人或者兩個人。顯然要求總重量不超過獨木舟承重,假設每個人體重也不超過獨木舟承重,問最少需要幾隻獨木舟?

分析: 

乙個顯然的策略是按照人的體重排序。

極端化貪心策略,最重的人要上船——如果最重的人和最輕的人體重總和不超過船的承重,則他們兩個占用一條船。否則(因為假設最重的人的體重也不超過船的承重了),最重的人單獨佔一條船。轉變為(n – 1)或者(n – 2)的問題了。

關鍵在於這種貪心策略是正確的。我們可以證明,最優解也可以變為這種策略。

(1) 假設最重的人和最輕的人的體重和超過了船的承重,那麼最優解中,顯然也是最重的人單獨佔一條船,所以這種情況下最優解和貪心策略是相同的。

(2) 假設最重的人和最輕的人的體重和沒超過船的承重。

(2.1)如果最優解中,最重的人單獨占用一條船,則可以把最輕的人也放上去,這樣最優解用的船數不增加。如果最輕的人占用一條船,同樣我們可以把最重的人放上去,最優解船數不增。

(2.2) 如果最優解中最重的人x和x』占用乙隻船(x, x』),而最輕的人y和y』占用乙隻船(y, y』)

我們換成(x, y) (x』,y』)

(x, y)顯然沒超過船的承重——因為我們假設就是如此。關鍵看(x』, y』)。

x』 + y』<= x』 + x 因為(x』, x)沒超重,所以(x』,y』)也合法。所以換一下,最優解船數也不增。這樣我們就證明了如果可能把最重的人和最輕的人放在一條船上,不會影響最優解。

反覆應用這個策略,就可以把n降低為(n – 1)或者(n – 2)個人的規模,從而解決這個問題。

最後,我們來提供輸入輸出資料,由你來寫一段程式,實現這個演算法,只有寫出了正確的程式,才能繼續後面的課程。

輸入

第一行包含兩個正整數n (0輸出

一行乙個整數表示最少需要的獨木舟數。

輸入示例

3 612

3

輸出示例

2
做的時候好鬱悶,本來弄了乙個遞迴,死活不過,又換了個姿勢發現還是不過....

剛開始用的while(1)後來換成while(i<=j)就過了,不知道為什麼.....

#include#include#includeusing namespace std;

typedef long long ll;

ll a[30000];

ll m;

int sum;

//void solve(int start,int end)

// if(a[start]+a[end]<=m)

// else

// // return;

//}int main()

sort(a,a+n);

//solve(0,n-1);

int i=0,j=n-1;

while(i<=j)

if(a[i]+a[j]<=m)

else }

printf("%lld\n",sum);

return 0;

}

獨木舟問題 51Nod

n個人,已知每個人體重。獨木舟承重固定,每只獨木舟最多坐兩個人,可以坐乙個人或者兩個人。顯然要求總重量不超過獨木舟承重,假設每個人體重也不超過獨木舟承重,問最少需要幾隻獨木舟?input 第一行包含兩個正整數n 0output 一行乙個整數表示最少需要的獨木舟數。input示例 3 612 3out...

51nod 獨木舟問題

n個人,已知每個人體重,獨木舟承重固定,每只獨木舟最多坐兩個人,可以坐乙個人或者兩個人。顯然要求總重量不超過獨木舟承重,假設每個人體重也不超過獨木舟承重,問最少需要幾隻獨木舟?分析 乙個顯然的策略是按照人的體重排序。極端化貪心策略,最重的人要上船 如果最重的人和最輕的人體重總和不超過船的承重,則他們...

51nod貪心例子獨木舟問題

n個人,已知每個人體重。獨木舟承重固定,每只獨木舟最多坐兩個人,可以坐乙個人或者兩個人。顯然要求總重量不超過獨木舟承重,假設每個人體重也不超過獨木舟承重,問最少需要幾隻獨木舟?使用貪心,先安排最重的與最輕的上船,假如此時獨木舟沒有超重,那麼此時只需要一輛船,否則把最終的安排上船,然後把次重的人與最輕...