zb的生日
时间限制:3000 ms | 内存限制:65535 KB
描述
-
输入
-
多组测试数据(<=1500)。数据以EOF结尾
第一行输入西瓜数量N (1 ≤ N ≤ 20)
第二行有N个数,W1, …, Wn (1 ≤ Wi ≤ 10000)分别代表每个西瓜的重量
输出
- 输出分成两堆后的质量差 样例输入
-
5 5 8 13 27 14
样例输出
-
3
分析:先求出所有的总和,如果要满足两堆差值最小,肯定是两者都为总和的一半时差值最小,求出中和的一半,用深搜去遍历,求出找到的数大于等于总和的一半时,计算另一堆,得出差值最小的,即为所求的值。
#include<math.h>
#include<stdio.h>
int a[101],book[101],m,n,flag,sum1,sum2,min;
void dfs(int cur,int sum)
{
int i,j;
if(sum>=m)
{
sum1=sum2=0;
for(i=0; i<n; i++)
{
if(book[i]!=0) //如果被标记说明被用到,而且被用到的数和满足条件
sum1+=a[i];
else if(!book[i])
sum2+=a[i];
}
if(min>fabs(sum1-sum2))
min=fabs(sum1-sum2);
return ;//返回之前一步
}
for(i=cur; i<n; i++) //从当前点开始循环
{
sum+=a[i]; //求满足条件的和
book[i]=1;//用过的数被标记,防止重复使用
dfs(i+1,sum); //递归调用,自己调用自己
sum-=a[i]; //返回上一级时和也与上一次同步
book[i]=0;//置零,尝试下一次
}
return;
}
int main()
{
int i,j,s;
while(~scanf("%d",&n))
{
s= sum1=sum2= flag=0;
min=999999;
for(i=0; i<n; i++)
{
scanf("%d",&a[i]);
s+=a[i];
}