描述
将一堆正整数分为2组,要求2组的和相差最小。例如:1 2 3 4 5,将1 2 4分为1组,3 5分为1组,两组和相差1,是所有方案中相差最小的
题解
设变量sum为整数数组的和。将整数数组分成两组,必然是一组的大于sum/2,记为sum_max,另一组小于sum/2,记为sum_min,最后的结果是sum-2*sum_min。
考虑sum_min,它其实就是一个背包问题:背包的容量为sum/2,物品的价值和权值均为该整数本身的大小。
由上分析可得下面的递推式子:
代码
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
#define maxn 105
int a[maxn], n,dp[10005];
int main(){
while(scanf("%d",&n)==1){
memset(dp,0,sizeof(dp))
int sum=0;
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
sum+=a[i];
}
int border=sum/2;
for(int i=0;i<n;i++){
for(int j=border;j>=a[i];j--){
dp[j]=max(dp[j],dp[j-a[i]]+a[i]);
}
}
int ans=sum-2*dp[border];
printf("%d\n",abs(ans));
}
}