POJ 2573 Bridge 【模擬+分治】
阿新 • • 發佈:2017-07-22
stream ans 通過 name -1 code 這樣的 返回 while a[1],a[2],a[n-1],a[n]分成一組,使用“好學生帶壞學生的思想”,於是就有了這樣的思路:
題目:
n人希望在晚上過河。 最多兩人可以組成一組一起過河,每組必須有手電筒。 在n個人中只有一個手電筒,所以必須安排過河順序,以便及時返回手電筒使得更多的人可以過河。
每個人的過河速度都不同; 每一組的速度由較慢成員的速度決定。 你的任務就是確定一個方案,讓所有的人在最短的時間內過河並且輸出方案。
分析:
此題其實本來是沒有思路的,但是 ,通過排序,我們發現:既然每次都得一個人傳遞手電筒,為什麽不讓最快的那個人傳呢(其實同時需要a[1],a[2]兩個人配合,詳見方案2)?又因為能者多勞,因此每次借助a[1],a[2]把最慢的兩位帶到對岸,而最快的兩位最後過河(經過簡單的貪心分析,不難看出這種決策是最優的),經排序,我們每次把
方案1:只借助a[1]幫a[n-1],a[n]過河;
1、a[1]帶a[n]過河 ==> a[n]
2、a[1]回去 ==> a[1]
3、a[1]帶a[n-1]過河 ==> a[n-1]
4、a[1]歸還手電 ==> a[1]
總時間:a[n]+a[n-1]+2*a[1]--------?
方案2:同時借助a[1]和a[2]幫a[n-1],a[n]過河;
1、a[1]和a[2]過河 ==> a[2]
2、a[1]回去 ==> a[1]
3、a[1]把手電給a[n-1]和a[n],a[n]和a[n-1]過河 ==> a[n]
4、a[2]歸還手電 ==> a[2]
總時間:a[n]+2*a[2]+a[1]-----------?
於是每次在決策的時候只要比較?和?的大小就好啦,先決策,輸出總時間,再輸出步驟。
參考代碼:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespacestd; int n,ans=0; int a[1010]; int main() { cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; if(n==1) { printf("%d\n%d\n",a[1],a[1]); return 0; } int nn=n; sort(a+1,a+n+1); while(n>3) { if(a[1]+a[n-1]<2*a[2]) ans+=a[n]+a[1]*2+a[n-1]; else ans+=a[2]*2+a[1]+a[n]; n-=2; } if(n==2) ans+=a[2]; else ans+=a[1]+a[2]+a[3]; printf("%d\n",ans); n=nn; while(n>3) { if(a[1]+a[n-1]<2*a[2]) printf("%d %d\n%d\n%d %d\n%d\n",a[1],a[n],a[1],a[1],a[n-1],a[1]); else printf("%d %d\n%d\n%d %d\n%d\n",a[1],a[2],a[1],a[n-1],a[n],a[2]);//記住要交還手電筒 n-=2; } if(n==2) printf("%d %d\n",a[1],a[2]); else printf("%d %d\n%d\n%d %d\n",a[1],a[3],a[1],a[1],a[2]); return 0; }
POJ 2573 Bridge 【模擬+分治】