n人过桥问题
n人过桥问题(Java)
过桥的两种方案
- 方案一:最快的和最慢的过桥,回来最快的,然后最快的和次慢的过桥,回来最快的。(明显的贪心法,好处:回来得快。)
- 方案二:最快的人和次快的先过桥,回来最快的,然后最慢的两个过桥,回来次快的。(好处:快的不会最慢的拖累)
判断当前使用那种过桥方案
当前如何过桥跟当前还未过桥的人数有关,主要分三大情况:
- 人数大于3:如果方案一time<方案二time ,使用方案一,否则使用方案二
- 人数等于2:直接两人过桥
- 人数等于3:方案一等价于方案二,并且最后不用回来一个人(因为运完了)。直接将三个人时间加起来即可
动态规划法
子问题的划分
根据上面的情况分析,划分子问题:
- 根据人数划分过桥情况
- 根据当前未过桥人用时划分使用方案
代码
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(); // 读取人数
int[] nums = new int[n+1];
Arrays.sort(nums);
for (int i = 1; i <= n; i++) {
nums[i] = sc.nextInt();
}
int result = 0;
int stay = n;
//大于三人
while(stay > 3){
//判断方案一快还是方案二,这里不等式化简了,自己写一下就知道了。
if(nums[1] + nums[stay-1] > 2*nums[2]) {
// 第二种方案
result += 2*nums[2] + nums[stay] + nums[1];
} else {
// 第一种方案
result += 2*nums[1] + nums[stay] + nums[stay-1];
}
//过桥了两人
stay -= 2;
}
if (stay == 3){
result += (nums[1] + nums[2] + nums[3]);
} else {
result += (nums[2]);
}
System.out.println("最短时间: " + result);
}
贪心算法
子问题的划分
根据上面的情况分析,划分子问题:
- 根据人数划分过桥情况。
- 只根据人数划分的情况使用方案一(贪心法)。
代码
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(); // 读取人数
int[] nums = new int[n+1];
//先排序
Arrays.sort(nums);
for (int i = 1; i <= n; i++) {
nums[i] = sc.nextInt();
}
int result = 0;
int stay = n;
//大于三人
while(stay > 3){
//只使用方案二
result += 2*nums[1] + nums[stay] + nums[stay-1];
//过桥了两人
stay -= 2;
}
if (stay == 3){
result += (nums[1] + nums[2] + nums[3]);
} else {
result += (nums[2]);
}
System.out.println("最短时间: " + result);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)