在这个问题中,我们需要将 n
个人划分为两个队伍,使得这两个队伍的体重之和尽可能相近。由于每个人都只能属于一个队伍,所以这是一个典型的划分问题。
划分问题通常可以使用动态规划算法来解决。在这个问题中,我们可以使用一个布尔型数组 dp[j]
来表示是否可以组成体重之和为 j
的一个队伍。我们首先将 dp[0]
设置为 true,表示可以组成体重之和为 0 的一个队伍。
接下来,我们遍历每个人的体重,对于每个体重 w[i]
,从总体重的一半开始向前遍历,如果前一个人的体重可以组成体重之和为 j - w[i]
的队伍,那么当前人的体重也可以用来组成体重之和为 j
的队伍。最终,我们可以找到体重之和尽可能相近的两个队伍。
因此,这个问题可以被转化为一个 0/1 背包问题,可以使用动态规划算法来求解。
#include <bits/stdc++.h>
using namespace std;
int main(){
int n;
while(cin>>n)
{
vector<int> w(n);
int sum=0;
for(int i=0;i<n;i++)
{
cin>>w[i];
sum+=w[i];
}
//动态规划求解
//大小为 totalSum / 2 + 1,并且每个元素的初始值都是 false
vector<bool>dp((sum/2)+1,false);
dp[0]=true;
//外层循环,遍历每个人的体重
for(int i=0;i<n;i++)
{
//内层循环,从总体重的一半往前遍历,直到当前体重w[i]
for(int j=sum/2;j>=w[i];j--)
{
dp[j] = dp[j] || dp[j-w[i]];
//如果当前体重w[i]可以用来组成体重之和为j的队伍,那么dp[j]==true
}
}
//找到最接近的体重之和
int sum1=0,sum2=0;
for(int j=sum/2;j>=0;j--)
{
if(dp[j])
{
sum1=j;
sum2=sum-j;
break;
}
}
cout<<min(sum1,sum2)<<" "<<max(sum1,sum2)<<endl;
}
return 0;
}