
本文介绍如何在给定总预算下,穷举所有满足价格约束的食品组合方案,每种食品以固定包装单位销售(如6根香肠/包),输出对应的实际件数而非单价组合。
本文介绍如何在给定总预算下,穷举所有满足价格约束的食品组合方案,每种食品以固定包装单位销售(如6根香肠/包),输出对应的实际件数而非单价组合。
要解决“在指定预算内列出所有可行食品采购组合”这一问题,核心在于将离散包装 + 单价 + 总预算转化为一个受约束的整数解空间搜索问题。原始代码试图用排列/阶乘生成价格排列,但混淆了“价格组合”与“可购买数量组合”——我们需要的是满足 5×w + 10×h + 15×f ≤ budget 的非负整数解 (w, h, f),其中:
- w = 购买的香肠包数(每包6根,单价 €5)
- h = 购买的汉堡包数(每包20个,单价 €10)
- f = 购买的弗里卡德尔包数(每包25根,单价 €15)
最终输出需转换为实际件数:6w 根香肠、20h 个汉堡、25f 根弗里卡德尔。
以下是一个清晰、可扩展、易于理解的 PHP 实现(兼容 PHP 7.4+,支持 readline() 动态输入预算):
<?php // 支持命令行交互式输入预算(需启用 readline 扩展)
if (function_exists('readline')) {
$input = readline("请输入预算(欧元): ");
$budget = (float)trim($input);
if ($budget <= 0 || !is_finite($budget)) {
die("错误:预算必须为正有限数值。\n");
}
} else {
// 回退到硬编码示例(生产环境建议启用 readline)
$budget = 200.0;
echo "注意:readline 未启用,使用默认预算 €200\n";
}
// 定义商品信息:[名称 => ['price_per_pack' => X, 'items_per_pack' => Y]]
$items = [
'worst' => ['price_per_pack' => 5, 'items_per_pack' => 6],
'hamburger' => ['price_per_pack' => 10, 'items_per_pack' => 20],
'frikandel' => ['price_per_pack' => 15, 'items_per_pack' => 25]
];
// 提取价格数组,保持顺序一致(用于嵌套循环)
$prices = array_column($items, 'price_per_pack');
$packSizes = array_column($items, 'items_per_pack');
$itemNames = array_keys($items);
// 存储所有有效组合
$combinations = [];
// 三层嵌套循环:暴力但直观,适合中小预算(预算≤500时性能良好)
$maxW = (int)floor($budget / $prices[0]); // 最多买多少包香肠
for ($w = 0; $w $budget) break;
$maxH = (int)floor(($budget - $costW) / $prices[1]);
for ($h = 0; $h $budget) break;
$maxF = (int)floor(($budget - $costWH) / $prices[2]);
for ($f = 0; $f $w * $packSizes[0],
'hamburger' => $h * $packSizes[1],
'frikandel' => $f * $packSizes[2],
'cost' => $totalCost
];
}
}
}
}
// 输出结果(按花费升序,便于观察性价比)
usort($combinations, fn($a, $b) => $a['cost'] $b['cost']);
echo "\n✅ 在 €{$budget} 预算内,共找到 " . count($combinations) . " 种可行组合:\n";
foreach ($combinations as $i => $combo) {
printf("• %d worsten, %d hamburgers, %d frikandellen (花费 €%.2f)\n",
$combo['worst'],
$combo['hamburger'],
$combo['frikandel'],
$combo['cost']
);
}
?>
✅ 关键设计说明:
- 逻辑清晰:使用三层确定性循环替代随机 shuffle 或递归排列,确保不遗漏、不重复;
- 单位转换正确:内部按“包数”计算成本,输出前乘以 items_per_pack 得到实际件数;
- 预算严格约束:≤ budget(非
- 健壮性增强:支持 readline() 交互输入,含输入校验;提供回退机制;
- 可扩展性强:只需修改 $items 数组即可新增/删减商品,无需重写核心逻辑。
⚠️ 注意事项:
- 对于高预算(如 €1000+),三层循环仍高效(因每层上限由预算反推,非固定大数);
- 若商品种类增加(≥4),建议改用回溯递归或动态规划优化,避免指数级增长;
- 实际部署时应添加 HTML 表单或 API 接口替代命令行,提升可用性。
该方案直击问题本质:不是排列价格,而是求解带约束的线性丢番图方程的非负整数解集,并以业务友好的方式呈现——这才是真正实用的预算组合计算器。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











