Initialize dp[0..] = 0. For each book (price, pages), update dp[] = max(dp[], dp[-price] + pages) for from down to price. The reverse iteration is key. If you go forward, you might count the same book multiple times (that's unbounded knapsack, not 0/1). Answer is dp[]. Time: , Space: . The code directly follows the recurrence relation. Trace through a small example by hand to see how each value is computed.
Time complexity: .
Space complexity: .