题目链接:
https://www.luogu.com.cn/problem/P2036
题目:
Perket 是一种流行的美食。为了做好 Perket,厨师必须谨慎选择食材,以在保持传统风味的同时尽可能获得最全面的味道。你有 n 种可支配的配料。对于每一种配料,我们知道它们各自的酸度 s 和苦度 b。当我们添加配料时,总的酸度为每一种配料的酸度总乘积;总的苦度为每一种配料的苦度的总和。
众所周知,美食应该做到口感适中,所以我们希望选取配料,以使得酸度和苦度的绝对差最小。
另外,我们必须添加至少一种配料,因为没有任何食物以水为配料的。
输入格式:
第一行一个整数 n,表示可供选用的食材种类数;
接下来 n 行,每行 22 个整数 Si 和 Bi,表示第 i 种食材的酸度和苦度。
输出格式:
一行一个整数,表示可能的总酸度和总苦度的最小绝对差。
例:
#1:
输入:
13 10
输出:
7
#2:
输入:
2
3 8
5 8
输出:
1
#3:
输入:
4
1 7
2 6
3 8
4 9
输出:
1
数据规定:
对于 100% 的数据,有 1≤n≤10,且将所有可用食材全部使用产生的总酸度和总苦度小于 1×,酸度和苦度不同时为 1 和 0。
思路:
该题是一个典型的枚举题。
我们可以使用dfs算法解决。
首先我们使用一个整形n来接收有几种香料,定义一个二维数组sou[n][2]来接收香料的酸度和苦度,定义一个布尔数组use[n]来判断该某种香料是否有使用过并且让use内部全部初始化为0\false,然后定义一个整形res为极大数,便于寻找最小的差值。
接下来使用dfs来寻找最小值,dfs函数使用一个deep来表示已使用了几种香料,一个suan表示之前香料的酸度之积,一个ku表示之前所使用香料的苦度之和
设置递归的边界条件为当deep等于香料总数时,让函数直接返回。若不返回,接下来循环寻找下一种没有使用过的香料,定义一个s_suan和s_ku表示之前所使用的香料的酸度之积和苦度之和,选择一个没有使用过的香料计算出目前PERKET的酸度和苦度,计算出酸度与苦度之差的绝对值,并且与res比较,取较小数,然后让其递归选择下一个香料。
最后会得到PERKET所使用香料的酸度与苦度的绝对值之差。
AC代码:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cmath>
using namespace std;
//sou中第0位为酸度,第一位为苦度
int n, sou[11][2], res = 999999999;
bool use[11] = { 0 };
void dfs(int deep, int suan, int ku) {
if (deep == n) {
return;
}
for (int i = 0; i < n; i++) {
int s_suan = suan, s_ku = ku;
if (!use[i]) {
use[i] = 1;
s_suan *= sou[i][0];
s_ku += sou[i][1];
res = min(res, abs(s_suan - s_ku));
dfs(deep + 1, s_suan, s_ku);
use[i] = 0;
}
}
}
int main() {
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d%d", &sou[i][0], &sou[i][1]);
}
dfs(0, 1, 0);
printf("%d", res);
return 0;
}
如果我的文章对你有所帮助,不妨给我个关注何点赞吧