法1
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 10;
int n;
long long ans = 1e8;
int s[N], b[N];
void dfs(long long sd, long long kd, int str)
{
int t = abs(sd - kd);
if(str != 0 && t < ans) ans = t;
//不是第一次进入才比较ans和t,因为第一次进入sd - kd为0,则ans一直为0,是错误的
for(int i = str; i < n; i ++)
if(sd == 0 && kd == 0) dfs(s[i], b[i], i + 1);
//第一次需要特判一下,因为存在sd = 0乘任何数都是0了,但kd是能加的
else dfs(sd * s[i], kd + b[i], i + 1);
//i + 1是起始位置
}
int main ()
{
cin >> n;
for(int i = 0; i < n; i ++) cin >> s[i] >> b[i];
dfs(0, 0, 0);
cout << ans;
return 0;
}
注意开longlong
与 P1036 [NOIP2002 普及组] 选数 类似
坑点:1 :long long
2: 第一次进入要特判
方法二
#include <algorithm>
#include <cstdio>
#include <cmath>
using namespace std;
int a[15],b[15],n,ans=1<<30; //a表示酸度,b表示甜度,ans为最终答案。
void dfs(int i,int sj,int th){
if(i>n){
if(!th) //如果没有选任何一种材料。
return ;
ans=min(ans,abs(sj-th)); //否则更新答案。
return ;
}
dfs(i+1,sj,th); //选
dfs(i+1,sj*a[i],th+b[i]); //不选
}
int main(){
int i;
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d %d",&a[i],&b[i]);
dfs(1,1,0); //搜索,注意酸度初始值一定为1,甜度初始值一定为0.
printf("%d",ans);
return 0;
}