Regionals 1996 >> Europe-northwestern
Problem Link: UVALive5583 UVA562 dividing coins.
Test Instructions Summary: Enter the number of test cases N, each test case includes the number of gold coins m and m positive integers are the value of gold coins. Divide these coins into two piles to minimize the difference and to find the smallest difference.
Problem analysis: You can solve this problem with the dynamic programming method of 0/1 knapsack . Set the backpack's capacity to half the sum of all gold coins, and put the pile of gold coins in the backpack as much as possible. Then calculate the difference.
0/1 Backpack Dynamic Programming method of the recursive type F (j,x), wherein the j=0,1,2,..., n-1 for items (total n items), X is the load capacity of the backpack. f (j,x) means: When the backpack load is X, the optional item is the optimal value of 0,1,2,..., J. The following are the specific formulas:
F ( -1,x) =-∞(x<0), F ( -1,x) =0 (x>=0)
F (j,x) =max{f (j-1,x), F (j-1 (X-WJ) +PJ} 0<=j<n,wj for Article J Item weight, PJ for article J article proceeds.
The program uses a two-dimensional array dp[][] to hold the value of the recursive function, compared to waste storage space, it should be used to construct a sparse matrix to store more reasonable.
In this procedure, Wj=coin[j] is the value of the currency, Pj=coin[j] that is the currency, a special case. The program logic is actually applied to the 0/1 knapsack recursive function.
The C language Program of AC is as follows:
/* UVALive5583 UVA562 dividing coins */#include <stdio.h> #include <memory.h> #define MAX (x, Y) (((x) > (y))? x):(y)) #define MAXN 100int DP[MAXN+1][MAXN * 500];int main (void) { int t, M, coin[maxn+1], sum, sum2, I, J; scanf ("%d", &t); while (t--) { scanf ("%d", &m); memset (coin, 0, sizeof (coin)); memset (DP, 0, sizeof (DP)); sum = 0; for (I=1; i<=m; i++) { scanf ("%d", &coin[i]); Sum + = Coin[i]; } sum2 = SUM/2; for (I=1; i<=m; i++) for (j=0; j<=sum2; j + +) if (J >= Coin[i]) dp[i][j] = MAX (dp[i-1][j), (dp[i-1 ][j-coin[i]] (coin[i])); else dp[i][j] = dp[i-1][j]; printf ("%d\n", sum-dp[m][sum2]-dp[m][sum2]); } return 0;}
UVALive5583 UVA562 Dividing coins