【BZOJ 2072】【POI2004】MOS

問題描述

一個夜晚一些旅行者想要過橋. 他們只有一個火把. 火把的亮光最多容許兩個旅行者同時過橋. 沒有火把或者多於2我的則不能過橋.每一個旅行者過橋都須要特定的時間, 兩個旅行者同時過橋時時間應該算較慢的那個. 咱們想知道全部旅行者最少要花費多少時間才能所有過橋? Example 假若有4我的. 他們分別須要花費6,7,10,15分鐘過橋.下圖演示了他們如何使用44分鐘所有過橋的,但他們能作得更快麼?spa

輸入格式

第一行一個數n 表示旅行者的總數, 1 ≤ n ≤ 100,000. 接下來n 行表示全部旅行者的過橋時間,時間從小到大排列,每一個數不超過1,000,000,000.code

輸出格式

輸出一個數表示最少過橋時間.blog

樣例輸入

4 io

6 class

7 di

10時間

15co

樣例輸出

42return

題解

算了十幾分鐘的樣例。。。|ू・ω・` )printf

樣例算出來就發現,一我的過橋了,除非要給別人送火把,不然顯然不會再回來。走得慢的人過橋的次數越少越好,走得快的人只能委屈一下多走幾回給別人送火把。因而最優決策有兩種,一種是走最快的人和走最慢的人過橋,走最慢的人留在對面,走最快的人把火把送回來;另外一種是走最快的人和走次快的人過去,最快的人留在對面,走次快的人把火把送回來,而後走最慢的兩我的過去。

設f[i]表示剩下i我的沒過橋所需的最少時間,a[i]表示第i我的過橋須要的時間

f[i][j]=min(f[i+1]+a[i+1]+a[1], f[i+2]+a[2]*2+a[1]+a[i+2])

 

 1 #include <cstdio>
 2 #define ll long long
 3 int n,a[100005];
 4 ll f[100005];
 5 ll min(ll x,ll y)
 6 {
 7     return x<y?x:y;
 8 }
 9 int main()
10 {
11     int i,j;
12     scanf("%d",&n);
13     for (i=1;i<=n;i++) scanf("%d",&a[i]);
14     if (n==1)
15     {
16         printf("%d",a[i]);
17         return 0;
18     }
19     for (i=n-1;i>=2;i--)
20     {
21         f[i]=f[i+1]+a[i+1]+a[1];
22         if (i<=n-2) f[i]=min(f[i],f[i+2]+a[2]*2+a[1]+a[i+2]);
23     }
24     printf("%lld",f[2]+a[2]);
25     return 0;
26 }
相關文章
相關標籤/搜索