思路: 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; }