【bzoj2072】【poi2004】【MOS】【dp+贪心】

本文探讨了一群旅行者过桥的问题,他们只有一个火把并需在有限时间内全部过桥。文章给出了两种可能的最优解策略,并通过动态规划算法实现了求解过程。

Description

一个夜晚一些旅行者想要过桥. 他们只有一个火把. 火把的亮光最多允许两个旅行者同时过桥. 没有火把或者多于2个人则不能过桥.每个旅行者过桥都需要特定的时间, 两个旅行者同时过桥时时间应该算较慢的那个. 我们想知道所有旅行者最少要花费多少时间才能全部过桥? Example 假如有4个人. 他们分别需要花费6,7,10,15分钟过桥.下图演示了他们如何使用44分钟全部过桥的,但他们能做得更快么?

Input

第一行一个数n 表示旅行者的总数, 1 <= n <= 100,000. 接下来n 行表示所有旅行者的过桥时间,时间从小到大排列,每个数不超过1,000,000,000.

Output

输出一个数表示最少过桥时间.

Sample Input

4
6
7
10
15

Sample Output

42

HINT

Source

STAGE 2

题解:可以发现最优解一定是以下两种情况。

          1.最快的人和最慢的人一起过去,最快的人回来

          2.最快的人和次快的人一起过去,最快的人回来,然后最慢的人和次慢的人一起过去,次快的人回来。

          然后dp即可。

代码:

#include<iostream>
#include<cstdio>
#define N 100010
using namespace std;
long long a[N],f[N];
int n;
int main(){
  scanf("%d",&n);
  for (int i=1;i<=n;i++) scanf("%d",&a[i]);
  if (n==1){cout<<a[1]<<endl;return 0;}
  for(int i=n-1;i>=2;i--){
     f[i]=f[i+1]+a[1]+a[i+1];
     if(i<=n-2)f[i]=min(f[i],f[i+2]+a[2]*2+a[1]+a[i+2]);
  }
  cout<<f[2]+a[2]<<endl;
}


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值