package 第03期.mca_10; import java.util.Arrays; // 来自小红书 // 实验室需要配制一种溶液,现在研究员面前有n种该物质的溶液, // 每一种有无限多瓶,第i种的溶液体积为v[i],里面含有w[i]单位的该物质 // 研究员每次可以选择一瓶溶液, // 将其倒入另外一瓶(假设瓶子的容量无限),即可以看作将两个瓶子内的溶液合并 // 此时合并的溶液体积和物质含量都等于之前两个瓶子内的之和。 // 特别地,如果瓶子A与B的溶液体积相同,那么A与B合并之后 // 该物质的含量会产生化学反应,使得该物质含量增加x单位 // 研究员的任务是配制溶液体积恰好等于c的,且尽量浓的溶液(即物质含量尽量多) // 研究员想要知道物质含量最多是多少 // 对于所有数据,1 <= n, v[i], w[i], x, c <= 1000 public class Code04_ChemicalProblem { public static int maxValue(int[] v, int[] w, int x, int c) { int n = v.length; // dp[0] ? dp[1] ? dp[2] ? dp[c] ? int[] dp = new int[c + 1]; // dp[i] = -1, 得到i体积,目前为止无方案 Arrays.fill(dp, -1); // 天然有的规格,先填一下 for (int i = 0; i < n; i++) { // 3 10 dp[3] = 10 // 5 13 dp[5] = 13 // 3 20 dp[3] = 20 if (v[i] <= c) { dp[v[i]] = Math.max(dp[v[i]], w[i]); } } // 1 ? 2 ? 3 ? c ? dp[1....c] for (int i = 1; i <= c; i++) { // i = 10体积 // 1 + 9 // 2 + 8 // 3 + 7 // 4 + 6 // 5 + 5 + x for (int j = 1; j <= i / 2; j++) { // dp[10] = dp[1] + dp[9] // 能得到 能得到 if (dp[j] != -1 && dp[i - j] != -1) { dp[i] = Math.max(dp[i], dp[j] + dp[i - j] + (j == i - j ? x : 0)); } } } return dp[c]; } public static void main(String[] args) { // 调配溶液 // 规格0 (体积5,含量2) // 规格1 (体积3,含量4) // 规格2 (体积4,含量1) // 合并双方体积不等的情况下 : // (体积5,含量2) + (体积4,含量1) = (体积9,含量3) // 合并双方体积相等的情况下 : // (体积5,含量5) + (体积5,含量2) = (体积10,含量5 + 2 + x) // x,额外增加,固定int类参数,x= 10 // c,一定要得到c体积的溶液,含量最大能是多少 ? int[] v = { 5, 3, 4 }; int[] w = { 2, 4, 1 }; int x = 4; int c = 16; // (体积3,含量4) + (体积3,含量4) = (体积6,含量12) // (体积3,含量4) + (体积3,含量4) = (体积6,含量12) // (体积6,含量12) + (体积6,含量12) = (体积12,含量28) // (体积12,含量28) + (体积4,含量1) = (体积16,含量29) System.out.println(maxValue(v, w, x, c)); } }