【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 }
相关文章
相关标签/搜索