Topic Meaning:给出n个数从中选a个数构成一组,剩下的b个数为一组,a与b的差值不超过1,求这两组数字总和差值最小时的两组的值。
Method of Solving:二维背包
dp[j][k]表示是否存在一组当其有k个数时,其值为j,以所有数字总和sum/2为第一状态上限,数字个数n/2为第二状态上限进行状态转移即可;
因为当dp[j][k]确定时,必然可知另外一组含n-k个数字,其数字总和为sum-j,结合题目要求可得出答案;
#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
int f[105],dp[50000][105];
int main(){
int n,sum;
while(cin>>n){
sum=0;
for(int i=1;i<=n;i++) {cin>>f[i];sum+=f[i];}
int mid=sum/2,half=(n+1)/2;
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for(int i=1;i<=n;i++)
for(int j=mid;j>=f[i];j--)
for(int k=half;k>0;k--)
if(dp[j-f[i]][k-1])
dp[j][k]=1;
int maxl=0,j;
for(j=mid;j>=0;j--)
if(dp[j][half]||dp[j][half-1])
break;
cout<<j<<' '<<sum-j<<endl;
}
return 0;
}
本文介绍了一种使用二维背包算法解决特定数字分组问题的方法。问题要求将n个数分为两组,每组数量相差不超过1,目标是使两组数字总和之差最小。通过设定状态dp[j][k]表示是否存在一组由k个数构成,其值为j,以数字总和一半和数量一半为上限进行状态转移,从而高效求解。

1388

被折叠的 条评论
为什么被折叠?



