I know this is an old question. But I had to spend some time on this, and I'm just documenting the approaches here for any future reference.
Method 1
A direct 2D method that uses N lines:
int dp[MAXN][MAXW]; int solve() { memset(dp[0], 0, sizeof(dp[0])); for(int i = 1; i <= N; i++) { for(int j = 0; j <= W; j++) { dp[i][j] = (w[i] > j) ? dp[i-1][j] : max(dp[i-1][j], dp[i-1][jw[i]] + v[i]); } } return dp[N][W]; }
In this case, the space O (NW) is used.
Method 2
The second method is also two-dimensional, but uses only 2 lines and continues to replace its roles with the current and previous.
int dp[2][MAXW]; int solve() { memset(dp[0], 0, sizeof(dp[0])); for(int i = 1; i <= N; i++) { int *cur = dp[i&1], *prev = dp[!(i&1)]; for(int j = 0; j <= W; j++) { cur[j] = (w[i] > j) ? prev[j] : max(prev[j], prev[jw[i]] + v[i]); } } return dp[N&1][W]; }
This occupies the space O (2W) = O (W). cur is the i-th line, and prev is the (i-1) -th line.
Method 3
The third method uses a 1D table.
int dp[MAXW]; int solve() { memset(dp, 0, sizeof(dp)); for(int i =1; i <= N; i++) { for(int j = W; j >= 0; j--) { dp[j] = (w[i] > j) ? dp[j]: max(dp[j], dp[jw[i]] + v[i]); } } return dp[W]; }
It also uses O (W) space, but just uses one line. The inner loop must be canceled because when we use dp[jw[i]] , we need the value from the previous iteration of the outer loop. For this, the values ββof j must be processed in a small way.
Test case (from http://www.spoj.com/problems/PARTY/ )
N = 10, W = 50 w[] = {0, 12, 15, 16, 16, 10, 21, 18, 12, 17, 18} // 1 based indexing v[] = {0, 3, 8, 9, 6, 2, 9, 4, 4, 8, 9}
answer = 26