题目:
今天是阴历七月初五,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<stdio.h>
#include<iostream>
#include<cstdlib>
#include<fstream>
using namespace std;
int melon[21];
int n;
int mins;//不要定义为min或max,以免与库函数冲突
int total;
void findmin(int i,int sum)//i为层数;sum为当前和
{
if(i==n) //到i = n;时,最后一次讨论是否包含[n-1];
{
int temp=abs(total - sum - sum);//当前两部分的差额
if(mins > temp)
mins=temp;
return;
}
/* 这里是一个剪枝;不用所有的都走到底部。
if(sum > total/2 )//如果当前的和已经大于一半,剪枝
{
int temp=abs(total - sum - sum);//当前两部分的差额
if(mins > temp)//如果最小差额比当前的差额大
{
mins = temp;
}
return ;
}
*/
findmin(i+1,sum);//不算melon[i]
findmin(i+1,sum+melon[i]);//算上melon[i]
}
int main()
{
int i;
while(cin>>n)
{
total=0;
mins=9999999;
for(i=0;i<n;i++)
{
scanf("%d",&melon[i]);
total+=melon[i];//西瓜总重量
}//for
if(n==0)
cout<<melon[0]<<endl;
else
{
findmin(0,0);
cout<<mins<<endl;
}
}//while
return 0;
}
深度优先,就是从一个点出发,一直深入下去,直到叶子节点,然后返回,在深入,直到
遍历完所有的节点,为了深刻的理解遍历的过程,可以单步跟踪一下。
单步跟踪:遇到函数按F11,进入函数;进入函数后按F10,单步走。这样就可以清楚的查看每一步。
下面就是跟从得到的树状图:
注释:输入的数据是: 2 1 2
就是从两个,分别是1和2 [0]代表第0个,[1]代表第1个。
遍历时就会把所有的情况都遍历一遍,每个元素都可能在或不在集合中。