1、题目描述
2、解题思路
深度优先搜索,选定一个基料,遍历配料,对于当前配料,有三种选择:
1、不选择;
2、选择用一次;
3、选择用两次;
计算上面三种选择的结果,进入三种DFS分支,具体看代码。
3、解题代码
int g_ans = INT_MAX; // 最接近 target 的成本
// 对第 idx 种配料,有 0、1、2 三种选择
void dfs(int *toppingCosts, int toppingCostsSize, int idx, int target, int sum)
{
if (abs(sum - target) < abs(g_ans - target)) { // 发现更接近 target 的成本
g_ans = sum;
} else if (abs(sum - target) == abs(g_ans - target) && sum < g_ans) { // 如果有多种方案,返回 成本相对较低的一种。
g_ans = sum;
} else if (sum >= target || idx == toppingCostsSize) { // 如果当前成本超过目标值,接下来只会越来越大,因此结束
return;
} else { // sum 还有接近 target 的空间
dfs(toppingCosts, toppingCostsSize, idx + 1, target, sum); // 不选当前配料
dfs(toppingCosts, toppingCostsSize, idx + 1, target, sum + toppingCosts[idx]); // 使用一次当前配料
dfs(toppingCosts, toppingCostsSize, idx + 1, target, sum + 2 * toppingCosts[idx]); // 使用两次当前配料
}
}
int closestCost(int *baseCosts, int baseCostsSize, int *toppingCosts, int toppingCostsSize, int target)
{
int sum = 0; // 当前成本
// 遍历基料
for (int i = 0; i < baseCostsSize; i++) {
sum = baseCosts[i]; // 选择当前基料
if (sum == target) { // 当前基料刚好等于 target
return target;
}
if (abs(sum - target) < abs(g_ans - target)) { // 发现更接近 target 的成本
g_ans = sum;
}
dfs(toppingCosts, toppingCostsSize, 0, target, sum); // 从第 0 个配料开始 dfs
if (g_ans == target) { // 找到等于目标成本的方案,提前结束
return g_ans;
}
}
return g_ans;
}