思路: 0/1背包
分析:
1 题目意思是有两个人分n个金币,要求最后两个人的金币差值最小
2 我们利用背包的思想即背包的总容量为金币总和的一半,去求出可以放入背包的最大的金币(这里其实就是某一个人能获得的最大的金币),那么最后的ans就是(sum-dp[sum/2])-dp[sum/2]
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 110;
const int MAXN = 50010;
int n , m , sum , v[N];
int dp[MAXN];
int solve(){
memset(dp , 0 , sizeof(dp));
int sumV = sum/2;
for(int i = 1 ; i <= m ; i++)
for(int j = sumV ; j >= v[i] ; j--)
dp[j] = max(dp[j] , dp[j-v[i]]+v[i]);
return (sum-dp[sumV])-dp[sumV];
}
int main(){
scanf("%d" , &n);
while(n--){
scanf("%d" , &m);
sum = 0;
for(int i = 1 ; i <= m ; i++){
scanf("%d" , &v[i]);
sum += v[i];
}
printf("%d\n" , solve());
}
return 0;
}