题目:过河
思路:动态规划
代码如下:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
public class Main {
//快速输入
static BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
//快速输出
static PrintWriter pw=new PrintWriter(new OutputStreamWriter(System.out));
public static void main(String[] args) throws IOException {
String[] s=br.readLine().split(" ");
int n=Integer.parseInt(s[0]);
s=br.readLine().split(" ");
long[] nums=new long[n];
for(int i=0;i<n;i++) {
nums[i]=Long.parseLong(s[i]);
}
//将数组排序
Arrays.sort(nums);
//对于n=1,2,3可以直接返回答案
if(n==1) {
pw.println(nums[0]);
}
else if(n==2) {
pw.println(nums[1]);
}
else if(n==3) {
pw.println(nums[0]+nums[1]+nums[2]);
}
else {
//dp[i]代表前i个数过河所需要的最小时间
long[] dp=new long[n+1];
dp[1]=nums[0];
dp[2]=nums[1];
dp[3]=nums[0]+nums[1]+nums[2];
for(int i=4;i<=n;i++) {
//前者为最大值和次大值一同过河,因为前i-2个人过河之后需要将船划回来,这时候选择过河后的数中的最小值。最大值和次大值过河后,河对面还有一个最小值没有过来,于是让当前岸最小值过去与其一同过来
//后者为最大值与最小值一同过河
//取两者的最小值
dp[i]=Math.min(nums[i-1]+dp[i-2]+nums[0]+nums[1]*2, dp[i-1]+nums[0]+nums[i-1]);
}
pw.println(dp[n]);
}
pw.flush();
}
}