a276: 又分糖果囉
Tags: subset-sum
出處:https://zerojudge.tw/ShowProblem?problemid=a276
提交:https://zerojudge.tw/Submissions?problemid=a276&account=allllllan123456
問題:給定 $n\in[1,20]$ 個數字 $\in[1,1000000]$,問你把這些數字「盡量平分 (總和)」為兩堆之後它們的差距 (最小) 是多少。
解法:此乃子集和問題,先算出總和 S 之後把這些數字用最佳策略塞進容量 S/2 的箱子內,那最後此箱子內的總體積就是其中一堆的和。唯一要注意的是這題不能用背包問題的 DP 方法,因為 1000000 實在是太大了,不論在時間或空間都是一種傷害,而且只有 20 個數字,因此 DFS 比較合理。
1#include <bits/stdc++.h>
2using namespace std;
3
4int n, totalsum, maX, m[20];
5
6void dfs(int index, int sum) {
7 if (sum > totalsum / 2) return;
8 if (sum > maX) maX = sum;
9 if (index == n) return;
10 dfs(index+1, sum + m[index]);
11 dfs(index+1, sum);
12}
13
14int main() { ios_base::sync_with_stdio(false); cin.tie(0); // IO 優化
15 while (cin >> n) {
16 maX = INT_MIN; totalsum = 0;
17 for (int i=0; i<n; i++)
18 cin >> m[i], totalsum += m[i];
19 dfs(0, 0);
20 cout << (totalsum-maX) - maX << '\n';
21 }
22 return 0;
23}