題目描述
今天是陰歷七月初五,acm隊員zb的生日。zb正在和C小加、never在武漢集訓。他想給這兩位兄弟買點什么慶祝生日,經過調查,zb發現C小加和never都很喜歡吃西瓜,而且一吃就是一堆的那種,zb立刻下定決心買了一堆西瓜。當他準備把西瓜送給C小加和never的時候,遇到了一個難題,never和C小加不在一塊住,只能把西瓜分成兩堆給他們,為了對每個人都公平,他想讓兩堆的重量之差最小。每個西瓜的重量已知,你能幫幫他么?
輸入
多組測試數據(<=1500)。數據以EOF結尾
第一行輸入西瓜數量N (1 ≤ N ≤ 20)
第二行有N個數,W1, …, Wn (1 ≤ Wi ≤ 10000)分別代表每個西瓜的重量
輸出
輸出分成兩堆后的質量差
樣例輸入
5
5 8 13 27 14
樣例輸出
3
代碼:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int N;
int weight[25]; //每個西瓜的重量
int total; //所有西瓜的總重量
int sum; //目前選擇的總重量
int res_min; //最終結果,最小的差
void dfs(int x, int sum){ //決定第x個西瓜要不要,目前選擇的西瓜的總重量為sum
if(x == N) //已經決定了N個西瓜了,完成任務,返回
return ;
int t = abs(total - 2 * sum); //目前的差值 = 多的-少的 = (總-少)-少 = 總-2*少
if(t < res_min) //更新最小差值
res_min = t;
dfs(x+1, sum); //遍歷不選擇第x個西瓜的情況,sum重量不變
dfs(x+1, sum+weight[x]); //遍歷選擇第x個西瓜的情況 ,在sum上加上第x個西瓜的重量
}
int main()
{
while(~scanf("%d",&N)){
total=0;
memset(weight, 0, sizeof(weight));
for(int i=0; i<N; i++){
scanf("%d",&weight[i]);
total += weight[i];
}
sum = 0; //目前選擇的總重量為0
res_min = 999999;
dfs(0,0); //決定了0個西瓜的選擇(即現在去決定第0+1=1個西瓜選不選),目前選擇的總重量為0
cout<<res_min<<endl;
}
return 0;
}