01背包 + 数学(平衡) 之 uva 562
// [7/21/2014 Sjm]
/*
题目关键:
Given a bag with a maximum of 100 coins, determine the most fair division between two persons.
This means that the difference between the amount each person obtains should be minimised.
思路:
两个人分硬币,要公平。那就让一个人所获得的硬币无限接近总的硬币的数目的一半(01背包求解),剩下的硬币给另外一个人。
此时,即可做到:"the difference between the amount each person obtains should be minimised. "
*/
1 #include <iostream> 2 #include <cstdlib> 3 #include <cstdio> 4 #include <algorithm> 5 #include <cstring> 6 using namespace std; 7 const int MAX = 50005; 8 int arr[105]; 9 int dp[MAX]; 10 int m, sum, Val; 11 12 int Solve() { 13 memset(dp, 0, sizeof(dp)); 14 for (int i = 1; i <= m; ++i) { 15 for (int j = Val; j >= arr[i]; --j) { 16 dp[j] = max(dp[j], dp[j - arr[i]] + arr[i]); 17 } 18 } 19 return abs(sum - 2 * dp[Val]); 20 } 21 22 int main() 23 { 24 //freopen("input.txt", "r", stdin); 25 int T; 26 scanf("%d", &T); 27 while (T--) { 28 sum = 0; 29 scanf("%d", &m); 30 for (int i = 1; i <= m; ++i) { 31 scanf("%d", &arr[i]); 32 sum += arr[i]; 33 } 34 Val = sum / 2; 35 printf("%d\n", Solve()); 36 } 37 return 0; 38 }