这题就是典型的位数贡献大于数量贡献, 1花的火柴更少,所以尽量用完10个1,然后其实就是简单的背包问题尽量拿最多的物品(数字),限重为300,各物品(数字)的重量即为所需火柴棒的数目,所以直接dp即可,当然也可以心算毕竟数据量不大,发现(2+5+5+4+5+3)*10=240,300-240=6*10,固有数字1,2,3,4,5,7,9各十个然后按照从小到大排序即可。
固答案为9999999999777777777755555555554444444444333333333322222222221111111111
import java.util.Scanner;
// 1: 无需 package
// 2: 类名必须 Main, 不可修改
public class Main {
public static void main(String[] args) {
System.out.println("9999999999777777777755555555554444444444333333333322222222221111111111");
}
}
用dp来做的代码即为(参考答案):
public class Main {
// 物品的重量数组,w[i]表示第i种物品的重量
static int[] w = {0, 6, 2, 5, 5, 4, 5, 6, 3, 7, 6};
// f数组用于存储动态规划的结果,f[i][j]表示前i种物品在不超过j重量的情况下的最大价值
static int[][] f = new int[11][310];
public static void main(String[] args) {
// 初始化f数组,这里假设所有物品的价值都是0,因为没有给出价值数组
for (int i = 0; i < f.length; i++) {
for (int j = 0; j < f[i].length; j++) {
f[i][j] = 0;
}
}
// 多重背包动态规划计算过程
for (int i = 1; i <= 10; ++i) { // 从第1种物品开始,到第10种物品
for (int j = 300; j >= w[i]; j--) { // 遍历所有可能的重量,从最大到w[i]
for (int k = 0; k <= 10; ++k) { // 遍历k个物品的组合
// 更新f[i][j]为当前物品加入后的最大价值
// 如果当前重量j大于等于k个物品i的重量,那么可以考虑加入k个物品i
if (j >= k * w[i]) {
f[i][j] = Math.max(f[i][j], f[i - 1][j - k * w[i]] + k); // 选择前i-1种物品的最大价值加上当前物品的价值
}
}
}
}
// 打印结果,从f[10][300]开始回溯找到选择的物品
int j = 300;
for (int i = 10, k = 0; i > 0; --i, k = 0) {
for (int g = 1; g <= 10; ++g) { // 遍历所有可能的选择数量
// 如果当前重量j减去g个物品i的重量仍然非负,并且f[i][j]等于f[i-1][j-g*w[i]]加上g个物品i的价值
if (j - g * w[i] >= 0 && f[i][j] == f[i - 1][j - g * w[i]] + g) {
k = g; // 更新选择的数量
}
}
// 根据选择的数量k,打印对应的物品编号(从0开始,所以减1)
for (j -= k * w[i]; k > 0; --k) {
System.out.print(i - 1);
}
}
}
}
由于对于基础算法忘得差不多了得去重新学习一下,这几天还在补充java数据结构和基础的函数调用,所以今天就做了几道,没做什么 。