题目描述
小明班里要举行一次拔河比赛,班主任决定将所有人分为两队,每个人都必须参加。两个队伍的人数之差不能超过1,并且两个队伍的体重之和要尽可能相近,当然相同是最好的了。
输入
输入包含多组测试数据。
每组输入的第一行是一个正整数n(2<=n<=100),表示共有n个人。
接下来n行,每行输入一个整数w(1<=w<=450),表示每个人的体重。
输出
对于每组输入,分别输出两个队伍的体重之和,按升序排序。
样例输入
3
100
90
200
样例输出
190 200
思路:
将所有组成的情况保存入表中,最后输出的时候,从表的中间部分往两头找!!!
代码如下:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int dp[101][50000];
int main()
{
int wight[101];
int n;
while(scanf("%d",&n)!=EOF)
{
memset(dp,0,sizeof(dp));
int sum = 0;
for(int i = 1 ; i <= n ; i++)
{
scanf("%d",&wight[i]);
sum += wight[i];
}
dp[0][0] = 1;
for(int i = 1 ; i <= n ; i++)
{
for(int j = min(n/2,i-1) ; j >= 0 ; j--)
{
for(int k = 0 ; k <= j*450 ; k++)
{
if(dp[j][k]) dp[j+1][k+wight[i]] = 1; //把所有可能的情况存入表中
}
}
}
int t = sum/2;
for(int i = 0 ; ; i++) //从中间往两端找
{
if(dp[n/2][t+i])
{
printf("%d %d\n",min(t+i,sum-t-i),max(t+i,sum-t-i));
break;
}
if(dp[n/2][t-i])
{
printf("%d %d\n",min(t-i,sum-t+i),max(t-i,sum-t+i));
break;
}
}
}
return 0;
}