题目
示例1
输入:
5 14 30 100
1 3 15 20 21 200 202 230
输出:
40
示例2
输入:
5 14 30 100
1 2 3 4 5 6 7 11 12 13
输出:
44
分析
解题思路
这个解决方案的步骤如下:
- 输入读取:
将每种票的价格(一日票、三日票、周票和月票)读入 pay 数组。
将minpay 设置为票价中的最小值。 - 读取计划游玩日期:读取计划游玩日期直到输入结束,存入 playday 数组。
- 动态规划方法:
初始化一个二维数组 dp,用于存储从第i天到第j天的最低消费。
dp[i][j]表示在这个范围内的最低消费。
将dp[i][i]初始化为minpay,因为在单日游玩的最低花费就是最低票价。 - 动态规划计算:
使用嵌套循环遍历计划游玩日期的所有子区间。
计算dp[j][j+i],考虑在j和j+i之间的所有可能拆分。
通过考虑连续日期之间的最小花费,以及购买1、3、7或30天票是否更经济,更新dp[j][j+i]。 - 输出:
输出从第0天到第 n-1天(n 是计划游玩日期的数量)的最低消费。
关键思想是使用动态规划a计算每个游玩日期子区间的最低消费,考虑不同的票选项。最终结果存储在dp[0] [n-1]中,表示整个计划期间的最低消费。
题解
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int[] pay = new int[4];
for (int i = 0; i < 4; i++) {
pay[i] = in.nextInt();
}
in.nextLine();
String[] str = in.nextLine().split(" ");
int n = str.length;
int[] playDay = new int[n];
int[][] dp = new int[n][n];
for (int i = 0; i < n; i++) {
playDay[i] = Integer.parseInt(str[i]);
dp[i][i] = pay[0];
}
for (int i = 1; i < n; i++) {
for (int j = 0; j < n - i; j++) {
dp[j][j + i] = dp[j][j + i - 1] + dp[j + i][j + i];
for (int k = j; k < i + j; k++) {
dp[j][j + i] = Math.min(dp[j][j + i], dp[j][k] + dp[k + 1][j + i]);
}
int days = playDay[j + i] - playDay[j] + 1;
if (days <= 3) {
dp[j][j + i] = Math.min(dp[j][j + i], pay[1]);
}
if (days <= 7) {
dp[j][j + i] = Math.min(dp[j][j + i], pay[2]);
}
if (days <= 30) {
dp[j][j + i] = Math.min(dp[j][j + i], pay[3]);
}
}
}
System.out.println(dp[0][n - 1]);
}
}
参考
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int[] pay = new int[4];
for (int i = 0; i < 4; i++) {
pay[i] = in.nextInt();
}
in.nextLine();
String[] str = in.nextLine().split(" ");
int n = str.length;
int[] playDay = new int[n];
int[][] dp = new int[400][400];
for (int i = 0; i < str.length; i++) {
playDay[i] = Integer.parseInt(str[i]);
dp[i][i] = pay[0];
}
for (int i = 1; i < n; i++) {
for (int j = 0; j < n - i; j++) {
dp[j][j + i] = dp[j][j + i - 1] + dp[j + i][j + i];
for (int k = j; k < j + i; k++) {
dp[j][j + i] = Math.min(dp[j][j + i], dp[j][k] + dp[k + 1][j + i]);
}
int days = playDay[j + i] - playDay[j] + 1;
if (days <= 3) {
dp[j][j + i] = Math.min(dp[j][j + i], pay[1]);
}
if (days <= 7) {
dp[j][j + i] = Math.min(dp[j][j + i], pay[2]);
}
if (days <= 30) {
dp[j][j + i] = Math.min(dp[j][j + i], pay[3]);
}
}
}
System.out.println(dp[0][n - 1]);
}
}
https://blog.csdn.net/weixin_52908342/article/details/135338098