这题就是典型的位数贡献大于数量贡献, 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个物品iif (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数据结构和基础的函数调用,所以今天就做了几道,没做什么 。