枚举所有非空食材组合,计算酸度乘积和苦度总和,取二者差值的最小值。
OJ: luogu
题目 ID: P2036
难度:入门
标签:枚举组合python
日期: 2026-07-15 21:50
题意
有 n 种食材,每种有酸度 s 和苦度 b。选择至少一种食材后:
- 总酸度是所有
s的乘积; - 总苦度是所有
b的和。
要求最小化 abs(总酸度 - 总苦度)。
思路
n <= 10,可以枚举所有非空组合。
对每个组合:
sour从1开始,乘上每个食材的酸度;bitter从0开始,加上每个食材的苦度;- 用
abs(sour - bitter)更新答案。
Python 知识
combinations(ingredients, size)枚举选size个食材的所有组合。answer = None可以表示“还没有任何候选答案”,避免随便写一个很大的初值。- 元组解包
for s, b in chosen让代码直接对应酸度和苦度。
参考笔记:
/home/rainboy/mycode/hugo-blog/content/program_language/python/brute_force_validation.md/home/rainboy/mycode/hugo-blog/content/program_language/python/math_tools.md
代码
python
from itertools import combinations
n = int(input())
ingredients = [tuple(map(int, input().split())) for _ in range(n)]
answer = None
for size in range(1, n + 1):
for chosen in combinations(ingredients, size):
sour = 1
bitter = 0
for s, b in chosen:
sour *= s
bitter += b
difference = abs(sour - bitter)
if answer is None or difference < answer:
answer = difference
print(answer)cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-07-27 00:00
* update_at: 2026-07-27 00:00
*/
#include <bits/stdc++.h>
using namespace std;
int n, ans = 2e9;
int s[15], b[15];
void dfs(int dep, int sour, int bitter, bool used) {
if (dep == n) {
if (used && abs(sour - bitter) < ans)
ans = abs(sour - bitter);
return;
}
dfs(dep + 1, sour, bitter, used); // 不放当前食材
dfs(dep + 1, sour * s[dep], bitter + b[dep], true); // 放
}
int main() {
cin >> n;
for (int i = 0; i < n; i++) cin >> s[i] >> b[i];
dfs(0, 1, 0, false);
cout << ans << endl;
return 0;
}复杂度
一共有 n 个食材,时间复杂度为
总结
数据范围很小,最稳妥的做法就是直接枚举所有非空选择,不要过度设计。