#include #include #include #define EVEN_PC 0 #define ODD_PC 1 #define N_DFT 20 #define T_DFT 500 #define ELT_BND 99 #define PLUS_INFINITY 1000000000 #define MINUS_INFINITY -1000000000 int *genarray ( int n, int PC ) { int i, *A, BND; if (PC == ODD_PC) BND = 2 * ELT_BND + 1; else BND = ELT_BND; A = (int *)malloc(n * sizeof(int)); for (i=0; i0): j is realizable from 0,1,2,...,i if and only if *** either j - a_i or j - b_i (odd pc) / j + b_i (even pc) is realizable *** from 0,1,2,...,i-1. *** *** We maintain a 2-d array S to store which sums are realizable. *** S[i][j] = 0 if the sum j is not realizable from indices 0,1,2,...,i. *** S[i][j] = a if a_i is chosen to realize the sum j. *** S[i][j] = b if b_i is chosen to realize the sum j. *** *** S[0][j] = a if and only if j = a_0 *** S[0][j] = b if and only if j = b_0 (odd pc) / -b_0 (even pc) *** *** We populate the i-th row S[i] by shifting S[i-1] by a_i and also by *** b_i (odd pc) / -b_i (even pc) and taking OR of the two shifted rows *** (both a and b are treated as logical 1). *** *** The final decision is available as S[n-1][T] (T = 0 for even pc). ***/ /* Shift S[i-1] (passed as p) by c and store in S[i] (passed as q) */ void addnmark ( char *p, char *q, int minsum, int maxsum, int c, char array ) { int i, j; for (i=minsum; i<=maxsum; ++i) { if (p[i]) { j = i + c; if (!q[j]) q[j] = array; } } } /* Function for both deciding the existence of a solution and printing if it exists */ void DPsolve ( int *A, int *B, int n, int T, int PC ) { int i, j, sum1, sum2, maxsum, minsum, shift; char **S, *p, *sol; /* The sums may be positive, negative, or zero. We first determine the minimum and maximum achievable sums. This is needed for allocating memory appropriately to the rows of S. */ sum1 = sum2 = 0; maxsum = MINUS_INFINITY; minsum = PLUS_INFINITY; if (PC == ODD_PC) { for (i=0; i= B[i]) { sum1 += A[i]; sum2 += B[i]; } else { sum1 += B[i]; sum2 += A[i]; } if (sum1 > maxsum) maxsum = sum1; if (sum2 < minsum) minsum = sum2; } } else { maxsum = minsum = 0; for (i=0; i=0; --i) { p = S[i] + shift; sol[i] = p[j]; if (p[j] == 'a') j -= A[i]; else if (PC == ODD_PC) j -= B[i]; else j += B[i]; } /* Print contributions from A */ printf("A : "); sum1 = 0; for (i=0; i= 2) ? atoi(argv[1]) : N_DFT; T = (argc >= 3) ? atoi(argv[2]) : T_DFT; printf("\n+++ FOR ODD PC\nn = %d\n", n); printf("A = "); A = genarray(n,ODD_PC); printf("B = "); B = genarray(n,ODD_PC); printf("T = %d\n", T); DPsolve(A,B,n,T,ODD_PC); printf("\n+++ FOR EVEN PC\nn = %d\n", n); printf("A = "); A = genarray(n,EVEN_PC); printf("B = "); B = genarray(n,EVEN_PC); DPsolve(A,B,n,0,EVEN_PC); exit(0); }