nyoj 47 過河問題(貪心)
p.s.emmm…如果寫的不好或者有錯的話一定要記得跟我說啊,千萬不要打我(肥宅大哭.jpg)這題寫的我真的是心塞T^T,我還是個孩子為什麼要這麼對我。
描述:
在漆黑的夜裡,N位旅行者來到了一座狹窄而且沒有護欄的橋邊。如果不借助手電筒的話,大家是無論如何也不敢過橋去的。不幸的是,N個人一共只帶了一隻手電筒,而橋窄得只夠讓兩個人同時過。如果各自單獨過橋的話,N人所需要的時間已知;而如果兩人同時過橋,所需要的時間就是走得比較慢的那個人單獨行動時所需的時間。問題是,如何設計一個方案,讓這N人儘快過橋。
輸入:
第一行是一個整數T(1<=T<=20)表示測試資料的組數
每組測試資料的第一行是一個整數N(1<=N<=1000)表示共有N個人要過河
每組測試資料的第二行是N個整數Si,表示此人過河所需要花時間。(0<Si<=100)
輸出
輸出所有人都過河需要用的最少時間
樣例輸入:
1
4
1 2 5 10
樣例輸出:
17
分析:首先是要分情況,當人數為一,二,三的時候便不多加描述了,因為坑點感覺是在四個人及以上啊。對於四個及以上的情況,有兩種方案:
第一種:讓用時最短的和最長的過去,最短的回來,帶第二長的走,如此迴圈(然後連樣例都過不了,WA的一聲哭出來)
第二種:用時最短的兩個過去,然後回來用時最短的,然後最長的兩個過去,然後第二短的回來,如此迴圈。
都是在剩下不到四個人的時候結束迴圈的。
其中兩種方案需要進行比較,從而選出用時最短的那種方案。(如果不知道為什麼要進行比較可以多寫幾組樣例體會一下)
程式碼如下
#include<stdio.h> #include<algorithm> using namespace std; int a[1010]; int main() { int t, n, i; scanf("%d",&t); while(t--) { scanf("%d",&n); for(i = 0; i < n; i++) scanf("%d",&a[i]); sort(a,a+n); int sum = 0; while(n >= 4) { if((a[1] * 2 + a[n-1] + a[0]) > (2 * a[0] + a[n-1] + a[n-2])) { sum += a[n-1]; sum += a[0]; sum += a[n-2];sum += a[0]; } else { sum += a[1]; sum += a[0];sum += a[n-1]; sum += a[1]; } n -= 2; } if(n == 3) sum += a[1] + a[0] + a[2]; else if(n == 2) sum += a[1]; else sum += a[0]; printf("%d\n",sum); } return 0; }
因為c語言實在有點菜。。。並沒有搞懂qsort。。。所以當時找了個老學姐要來了c++的排序方式,以至於寫的實在一言難盡,下面是補的手寫排序函式(裝死):
void sort(int*arr,int length)
{
int i=length,j=0;
int t;
while(i--)
{
j=i;
while(j--)
{
if(arr[i]>arr[j])
{
t=arr[i];
arr[i]=arr[j];
arr[j]=t;
}
}
}
}
sort(r,length);
為何這部落格寫的我如此心累。。。我實名diss那個學姐T^T,竟讓我們寫部落格。