
本文介绍一种基于贪心策略的算法,用于在给定各产品库存数量的前提下,求出最多能组成多少组“每组恰好包含指定种类数(如2种)产品”的有效组合,确保每次组合都严格选取指定数量的不同产品各1个。
本文介绍一种基于贪心策略的算法,用于在给定各产品库存数量的前提下,求出最多能组成多少组“每组恰好包含指定种类数(如2种)产品”的有效组合,确保每次组合都严格选取指定数量的不同产品各1个。
在电商库存调度、资源配对或组合优化等场景中,常遇到如下问题:已知若干产品的当前库存量(例如 [4, 4, 2]),要求每次从不同产品中各取1个单位组成一组(如必须含且仅含2种产品),问最多能组成多少组?关键约束是:每组必须严格包含指定数量 $k$ 种不同的产品(不可少、不可多),且同一产品在单组中不可重复使用。
该问题本质是受限的“多维资源配对”问题。直观上,若将库存数组按降序排列,最优策略应始终优先消耗当前库存最多的 $k$ 种产品——这正是贪心思想的核心:每次从库存最高的 $k$ 个产品中各减1,直到无法选出 $k$ 个非零库存的产品为止。
以下为清晰、健壮的 PHP 实现:
<?php
$required_products = 2; // 每组必需的产品种类数(固定为2)
$group_iten = [4, 4, 2]; // 各产品当前库存量
// 步骤1:降序排序,确保每次优先选库存最多的k个
rsort($group_iten);
$count = 0;
// 步骤2:循环条件:第k个元素(索引为 k-1)仍 > 0
// 表明至少有k个产品库存 ≥ 1,可构成一组
while (count($group_iten) >= $required_products && $group_iten[$required_products - 1] > 0) {
// 从库存最高的前k个产品中各取1个
for ($j = 0; $j < $required_products; $j++) {
$group_iten[$j]--;
}
// 重新降序排序,为下一轮选择做准备
rsort($group_iten);
$count++;
}
echo "最大可能组合数: " . $count; // 输出:5
?>执行过程示例([4,4,2]):
- 初始:
[4,4,2]→ 取前2个 →[3,3,2](计数1) - 排序后:
[3,3,2]→[2,2,2](2) -
→ [2,1,1]→ 排序[2,1,1]→[1,0,1](3) - 排序
[1,1,0]→[0,0,0]?注意:实际第4步后为[1,1,0],排序得[1,1,0],再取前2个得[0,0,0](4)?
但正确跟踪应为:
-
[4,4,2]→[3,3,2] -
[3,3,2]→[2,2,2] -
[2,2,2]→[1,1,2]→ 排序 →[2,1,1] -
[2,1,1]→[1,0,1]→ 排序 →[1,1,0] -
[1,1,0]→[0,0,0]→ 此时$group_iten[1] === 0,循环终止,总计 5 组。
关键注意事项:
- ✅ 必须在每次减量后调用
rsort(),否则无法保证下一轮选取的是当前库存最高的 $k$ 个; - ✅ 循环条件
&& $group_iten[$required_products - 1] > 0是核心:它等价于“至少有 $k$ 个产品库存 ≥ 1”,比检查count($group_iten) >= $required_products更精准(因数组中可能存在0值但未被 unset); - ⚠️ 原始算法错误在于:未全局重排序、错误使用
unset导致索引错位、且未聚焦“维持 $k$ 个非零库存”这一本质条件; - ? 时间复杂度为 $O(C \cdot n \log n)$,其中 $C$ 为最终组合数,$n$ 为产品种类数;对中小规模数据高效可靠。
该方法简洁、可扩展(只需修改 $required_products 即可适配3种、4种等场景),是解决此类“固定维度资源配对最大化”问题的标准贪心解法。

















