复制Markdown 展开
题目描述
Perket 是一种流行的美食。为了做好 Perket,厨师必须谨慎选择食材,以在保持传统风味的同时尽可能获得最全面的味道。你有 𝑛 种可支配的配料。对于每一种配料,我们知道它们各自的酸度 𝑠 和苦度 𝑏。当我们添加配料时,总的酸度为每一种配料的酸度总乘积;总的苦度为每一种配料的苦度的总和。
众所周知,美食应该做到口感适中,所以我们希望选取配料,以使得酸度和苦度的绝对差最小。
另外,我们必须添加至少一种配料,因为没有任何食物以水为配料的。
输入格式
第一行一个整数 𝑛,表示可供选用的食材种类数。
接下来 𝑛 行,每行 2 个整数 𝑠𝑖 和 𝑏𝑖,表示第 𝑖 种食材的酸度和苦度。
输出格式
一行一个整数,表示可能的总酸度和总苦度的最小绝对差。
输入输出样例
输入 #1
1
3 10
输出 #1
7
输入 #2
2
3 8
5 8
输出 #2
1
输入 #3
4
1 7
2 6
3 8
4 9
输出 #3
1
说明/提示
数据规模与约定
对于 100% 的数据,有 1≤𝑛≤10,且将所有可用食材全部使用产生的总酸度和总苦度小于 1×10^{_{9}},酸度和苦度不同时为 1 和 0。
思路
这道题也是可以使用dfs进行所有情况的遍历,不过这道题增加了点小难度,它没有限制达到目标所需的元素个数,所以我们需要从1遍历到 n,如何实现呢?只需设置一个全局变量point,在solve中增加一个for循环,point初始值为1,每次循环后就point++,这样就可以实现遍历1到 n 的元素次数。
再者就是当元素个数达到目标时,要判断是否满足条件:酸度和苦度的绝对差最小。对呀酸度,总的酸度为每一种配料的酸度总乘积;对于苦度,总的苦度为每一种配料的苦度的总和。
所以在if语句中再统计总酸度和总苦度,然后与最小值Min判断,求最小值。
在这里要提醒一下,这些食物是携带一酸度和一苦度的,同一行酸度和苦度不是分离的,我一开始以为是各算各的,想了很久最后在发现题目没审好( 所以还是要好好审题啊๛ก(ー̀ωー́ก) )
好啦,接下来就是你们最关心的AC代码啦!
AC代码
#include<iostream>
#include<math.h>
using namespace std;
typedef long long ll;
ll dis = 0x3f3f3f3f;//设置个最大值
ll Min = 0x3f3f3f3f;
int point,n;
int vec[12][12];
int a[12];
void dfs(int step,int start) {
if (step == point) {
ll suan = 1;
ll ku = 0;
for (int i = 0; i < point; i++) {
suan *= vec[a[i]][1];
ku += vec[a[i]][2];
}
dis = abs(suan - ku);
if (dis < Min) {
Min = dis;
}
return;
}
for (int i = start; i <= n; i++) {
a[step] = i;
dfs(step + 1,i + 1);
a[step] = 0;
}
}
void solve()
{
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> vec[i][1] >> vec[i][2];//酸度和苦度
}
for (int i = 1; i <= n; i++) {
point = i;
dfs(0, 1);
}
cout << Min;
}
int main()
{
int t = 1;
cin.tie(0)->ios::sync_with_stdio(false);
while (t--) {
solve();
}
return 0;
}