四人过桥问题与扩展(DP,其实也可以看成贪心)

本文探讨了一个经典的逻辑问题——4人过桥,分析了如何通过策略优化使得所有人过桥时间最短。文章详细阐述了解决思路,包括让速度快的人来回传递手电筒以及尽量让过桥时间相近的两人一起过桥。通过动态规划的算法实现,得出最少时间为17分钟的解决方案,并提供了Java代码示例来验证这一过程。
摘要由CSDN通过智能技术生成

4个人在晚上过一座小桥,过桥时必须要用到手电筒,只有一枚手电筒,每次最多只可以有两人通过, 4个人的过桥速度分别为1分钟A、2分钟B、5分钟C、10分钟D,试问最少需要多长时间4人才可以全部通过小桥?

答案是17分钟
先让A,B过桥(2分钟),再让A返回(1分钟),然后C,D一起过桥(10分钟),B返回(2分钟),最后A,B一起过桥(2分钟)。

我们来想一下这个过桥问题的能减少时间的地方:

  1. 让过桥时间少的人来传递手电筒
  2. 让过桥时间相差最小的两个人一起过桥(两人过桥取两者时间最大值)

解决思路:

针对因素1,让过桥时间少的人先过桥,这样他们可以回来传递手电筒。
针对因素2,将每个人按过桥时间进行排序,每次过桥取相邻的两个人,此时过桥时间相差最小。

方案:
先对每个人按过桥时间进行排序,然后按过桥时间长短进行过桥。我们使用DP来解

  1. 确定状态:
    dp[i]:代表前i个人过桥所用的时间

  2. 转移方程:

dp[i]=min(dp[i-2]+a[1]+a[i]+a[2]+a[2],dp[i-1]+a[1]+a[i]);

第一种:对岸有两个人,让1,2来接,先让1过去(a[1]),然后i-1和i 两人过桥(a[i]),2再来接1(a[2]),1和2一起过桥(a[2])。
第二种:对岸有一个人,让1来接,先让1过去(a[1]),然后1和i一起过桥回来(a[i])。

  1. 初始值和边界情况
    只有一个人或两个人过桥,不能被转移方程推导出来
dp[1]=a[1];
dp[2]=a[2];

边界为人数即可,求多了也没用

  1. 计算顺序,从小到大
package Demo1;

import java.util.Arrays;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        int n=scanner.nextInt();
        int a[]=new int[n+1];
        for(int i=1;i<=n;i++){
            a[i]=scanner.nextInt();
        }
        Arrays.sort(a);
        if(n==1){
            System.out.println(a[1]);
            return;
        }
        if(n==2){
            System.out.println(a[2]);
            return;
        }
        int dp[]=new int[n+1];
        dp[1]=a[1];
        dp[2]=a[2];
        for(int i=3;i<=n;i++){
            dp[i]=Math.min(dp[i-2]+a[1]+a[i]+a[2]+a[2],dp[i-1]+a[1]+a[i]);
        }
        System.out.println(dp[n]);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值