将基础的01背包 稍微的转化了一点,、
题意就是让你求出N个硬币,然后分成两组求两组的差值最小为多少,不能为负、
大概思路就是如果我想要找到最小的值的话,那么我们首先是知道所有得数的和sum,既然想找到差值最小,只需要求以(sum/2) 位容量,每个硬币的值为单位容量、
只要求出满足容量的最大值便可以了、
分析:因为是想要找出N个硬币分成两组合值的差值值的最小值,所以我们可以先求一组我想要的值,既然知道所有硬币的总值sum,所以当然我想要满足其中一组
的最大值为sum/2是最好的,但是它不一定可以为sum/2,所以就要求出在尽量装满sum/2的最大值、 所以最小的差值为sum-dp[N]*2、
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=110000;
int T;
int N;
int V;
int VV;
int w[maxn];
int dp[maxn];
int main()
{
scanf("%d",&T);
while(T--){
scanf("%d",&N);
V=0;
memset(dp,0,sizeof(dp));
for(int i=0;i<N;i++){
scanf("%d",&w[i]);
V+=w[i];
}
VV=V/2;
for(int i=0;i<N;i++){
for(int j=VV;j>=w[i];j--){
dp[j]=max(dp[j],dp[j-w[i]]+w[i]);
}
}
printf("%d\n",V-dp[VV]*2);
}
return 0;
}