POJ - 3404 Bridge over a rough river (DP)

Bridge over a rough river

Description

A group of N travelers (1 ≤ N ≤ 50) has approached an old and shabby bridge and wishes to cross the river as soon as possible. However, there can be no more than two persons on the bridge at a time. Besides it's necessary to light the way with a torch for safe crossing but the group has only one torch.

Each traveler needs ti seconds to cross the river on the bridge; i=1, ... , N (ti are integers from 1 to 100). If two travelers are crossing together their crossing time is the time of the slowest traveler.

The task is to determine minimal crossing time for the whole group.

Input

The input consists of two lines: the first line contains the value of N and the second one contains the values of ti (separated by one or several spaces).

Output

The output contains one line with the result.

Sample Input

4
6 7 6 5

Sample Output

29



题意:每次可以两个人过桥,过桥的时间为走的最慢的那个,然后让一个人回来,求最短的过桥时间。


解题思路:很有意思的一道题目,不知道是用了贪心的思想还是动态规划。我认为一开始是贪心的思考,然后找到最佳决策,然后再用dp的思想去实现,前面的i个人的最少时间,对后面肯定没有影响。首先对时间进行排序,一开始肯定是想让走得最快的人跟过去,这样回来的时候就可以省下很多时间,但是这样子会有一个问题,就是这边可能会有两个走得很慢的人,这样就会多花一倍的时间,实际上应该是判断是让这边走得最慢的两个过去,然后让对面走得最快的回来,还是让这边走得最快的和一个最慢的过去快,用一个min函数判断就好了。



#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <map>
#include <string.h>
#include <algorithm>
#include <queue>
#define INF 1<<29
using namespace std;

int N;

int dp[100];
int a[100];

int main(){

    while(~scanf("%d",&N)){

        for(int i=1;i<=N;i++)
                scanf("%d",&a[i]);

        //排完序后a[1]为走的最快的
        sort(a+1,a+N+1);

        dp[1]=a[1];
        dp[2]=a[2];

        for(int i=3;i<=N;i++)
             dp[i]=min(dp[i-1] + a[1] + a[i],dp[i-2] + a[1] + a[i] + 2*a[2]);
        //前者的意思是当这边还有一个人的时候,肯定是让对面走得最快的回来
        //后者的意思是当这边还有两个人(其中一个肯定是a[1])的时候,肯定是让对面走得最快(这个时候是a[2])的回来,然后让a[1]和a[i]过去,a[1]回来,再a[1]a[2]过去

        printf("%d\n",dp[N]);
    }

    return 0;
}







  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值