采用遞歸法的方式進行題解。
思路:首先我們知道在n種材料當中,我們需要從中選擇至少有一種得配料才行。也就是說,我們選擇的配料數目是自己決定的,而不是那種組合型得對于你有要求的組合型遞歸方式。
所以我們會想到用指數型得遞歸來解決這個問題。這一點需要自己首先判斷明白。
第二點,我們知道,在選數得過程中我們需要根據題目的條件進行判斷這種配料的酸度和苦度,因此,在我們結束遞歸的時候需要進行計算我們已經存儲的方案得和和乘積,然后再進行相減取絕對值計算。
當然,這里也有比較坑得點,那就是,當我們在判斷沒有方案的時候我們需要知道,這個時候我們定義的daiti是沒有發生變化的,這里為什么需要用到daiti這個變量是因為這個原因,因為乘法的累乘需要我們在初始值為1得情況下進行的,所以我需要再定義一個變臉sum1進行賦值,當daiti沒有發生變化的時候,說明我們的是沒有方案的。因此,這樣就判斷完畢了。
注意:當我們在函數中判斷完畢之后,那么我們還需要知道一件事,就是在全部不選擇配料的時候,這個結果我們也會放在數組里面,這個時候最終結果就是0,始終是0,這個時候我們需要找到第二個小的數,所以在找到最小的數之后賦予一個大的數,然后再繼續遍歷選出除最小值以外的最小數就行了。
上代碼:
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<algorithm>
#include<stack>
#include<queue>
#include<sstream>
#include<map>
#include<limits.h>
#include<set>
#define MAX 40
#define _for(i,a,b) for(int i=a;i<(b);i++)
#define ALL(x) x.begin(),x.end()
using namespace std;
typedef long long LL;
LL n, m, counts=1;
LL arr[MAX][MAX];
LL res = 10e9;
LL st[MAX];
LL cunchu[MAX];
void dfs(int u) {if (u > n) {LL sum1 = 0;LL daiti = 1;LL sum2 = 0;_for(i, 1, n + 1) {if (st[i] == 1) {daiti *= arr[i][1];sum2 += arr[i][2]; }}if (daiti != 1)sum1 = daiti;cunchu[counts++] = abs(sum1 - sum2);return;}st[u] = 1;dfs(u + 1);st[u] = 0;st[u] = 2;dfs(u + 1);st[u] = 0;
}
int main() {ios::sync_with_stdio(false);cin.tie(NULL); cout.tie(NULL);cin >> n;_for(i, 1, n + 1) {_for(j, 1, 3)cin >> arr[i][j];}dfs(1);LL index = 0;LL maxs = INT_MAX;_for(i, 1, counts){if (maxs > cunchu[i]) {maxs = cunchu[i];index = i;}}cunchu[index] = INT_MAX;_for(i, 1, counts) {res = min(res, cunchu[i]);}cout << res;return 0;
}
當然,這是比較笨的寫法,但是我們需要進行優化一下,對于dfs暴搜來說,在main函數的調用中我們需要簡介一些,接下來就是在判斷沒有方案的時候進行優化了一下,也就是定義一個flag標志,這樣在遍歷的時候就能知道到底有沒有方案了。
下面是優化之后的代碼:
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<algorithm>
#include<stack>
#include<queue>
#include<sstream>
#include<map>
#include<limits.h>
#include<set>
#define MAX 50
#define _for(i,a,b) for(int i=a;i<(b);i++)
#define ALL(x) x.begin(),x.end()
using namespace std;
typedef long long LL;
LL n, m, counts=1;
LL arr[MAX][MAX];
LL res = 10e9;
LL st[MAX];
LL cunchu[MAX];
bool flag = false;
void dfs(int u) {if (u > n) {flag = false;LL sum1 = 1;LL sum2 = 0;_for(i, 1, n + 1) {if (st[i] == 1) {flag = true;sum1 *= arr[i][1];sum2 += arr[i][2]; }}if (flag) {res = min(res, abs(sum1 - sum2));}return;}st[u] = 1;dfs(u + 1);st[u] = 0;st[u] = 2;dfs(u + 1);st[u] = 0;
}
int main() {ios::sync_with_stdio(false);cin.tie(NULL); cout.tie(NULL);cin >> n;_for(i, 1, n + 1) {_for(j, 1, 3)cin >> arr[i][j];}dfs(1);cout << res;return 0;
}