Step 1 题前闲话
显而易见,这是一道DFS,相比是一道回溯(也不知道是谁一看到这道题就急着用贪心。)
Step 2 分析题意
给四个数和三个符号,每次任意选取两个数按顺序按照符号结合。最终四个数和三个符号会合成一个数。最小的结果即为答案。
Step 3 解题思路
考虑搜索,每次选两个数与符号依次结合。每选择一次,我们就将其中一个数标记,然后将两个数结合后的答案回溯。最终我们进行三次结合后,我们扫一下标记数组,现在没有被标记的那一个就是这一轮的答案了。
再谈一下回溯。我们每次搜索完下一层之后,只需要将标记数组还原,然后将改变的数组的那一项的值也还原就好。
Step 4 AC code
#include<bits/stdc++.h>
using namespace std;
long long a[5],ans=1e14;
char b[4];
void dfs(int fin){//dfs
if(fin == 4){//已经找完第四个数
for(int i = 1; i <= 4; i++){
if(a[i] >= 0 && a[i] < ans) ans = a[i];
}
}
for(int i = 1; i < 4; i++){
for(int j = i + 1; j <= 4; j++){
if(a[i] >= 0 && a[j] >= 0){
long long temp = a[i], tempp = a[j];
if(b[fin] == '+')a[i] += a[j];
else a[i] *= a[j];
a[j]=-1;
dfs(fin+1);//查找下一个数
a[i]=temp;
a[j]=tempp;
}
}
}
}
int main(){
for(int i = 1; i <= 4; ++i){
scanf("%lld",&a[i]);
}
for(int i = 1; i <= 3; ++i){
cin>>b[i];
}
dfs(1);
cout<<ans<<endl;
return 0;
}