Java中满足X与Y数量相等约束的对象数组最大收益计算求助
解决32个对象选16X16Y的最大收益问题
嘿,这个问题我太懂了!之前处理4个对象这种小数据集时,手动枚举组合确实好使,但32个对象里选16个当X、16个当Y,那组合数简直天文数字——算下来有六亿多组,完全不可能枚举完。别慌,咱们换个思路,用排序就能高效解决,甚至不用复杂的动态规划!
先明确问题模型
我先默认你的场景是:每个对象既可以被选为X获得收益x[i],也可以被选为Y获得收益y[i],要求必须选16个X和16个Y,最终总收益最大。如果你的场景有其他约束(比如X/Y有依赖关系),可以再补充说明,但先讲最常见的这种情况。
核心思路:转化问题,用排序找最优解
我们可以把总收益的计算方式转化一下:
总收益 = 所有对象都选X的收益总和 + 把部分对象换成Y带来的收益增量
每个对象从X换成Y的收益增量是 diff[i] = y[i] - x[i]:
- 如果
diff[i]是正的,说明换成Y能增加总收益; - 如果是负的,换成Y会减少总收益。
那要最大化总收益,我们只需要选出16个diff[i]最大的对象换成Y,剩下的16个保持为X就行——因为这16个增量是最大的,能让总收益提升最多。
Java代码实现
先定义一个存储每个对象收益的类,然后写计算逻辑:
// 存储每个对象的X/Y收益,以及收益差值 class ProfitItem { int xProfit; int yProfit; int diff; // yProfit - xProfit,即换成Y的收益增量 public ProfitItem(int x, int y) { this.xProfit = x; this.yProfit = y; this.diff = y - x; } } public class MaxProfitSolver { public static int calculateMaxProfit(List<ProfitItem> items, int requiredXCount) { // 先计算所有对象都选X的总收益 int totalXSum = items.stream() .mapToInt(item -> item.xProfit) .sum(); // 按收益增量diff从大到小排序 items.sort((a, b) -> Integer.compare(b.diff, a.diff)); // 选出前(总数量 - requiredXCount)个最大的diff,求和就是最大的收益增量 int maxDiffSum = items.stream() .limit(items.size() - requiredXCount) .mapToInt(item -> item.diff) .sum(); // 总收益 = 全选X的收益 + 最大增量 return totalXSum + maxDiffSum; } public static void main(String[] args) { // 模拟32个测试对象 List<ProfitItem> items = new ArrayList<>(); Random random = new Random(); for (int i = 0; i < 32; i++) { int x = random.nextInt(100); int y = random.nextInt(100); items.add(new ProfitItem(x, y)); } // 计算选16个X、16个Y的最大收益 int maxProfit = calculateMaxProfit(items, 16); System.out.println("最大收益为:" + maxProfit); } }
为什么这个方法高效?
整个过程的时间复杂度是O(n log n),主要来自排序步骤——32个元素排序完全是瞬间完成的,和枚举六亿组的效率天差地别。而且这个解法是全局最优的,不是近似解,完全符合你的需求。
如果你的问题有其他特殊约束(比如选X必须满足某些条件,或者X/Y之间有依赖),可以再补充细节,我再帮你调整解法!
内容的提问来源于stack exchange,提问作者bram993
相关产品推荐
相关产品推荐

