Open In App

CSES Solutions – Book Shop

Last Updated : 02 Apr, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

You are in a book shop which sells N different books. You know the price and number of pages of each book.

You have decided that the total price of your purchases will be at most X. What is the maximum number of pages you can buy? You can buy each book at most once.

Examples:

Input: N = 4, X = 10, price[] = {4, 8, 5, 3}, pages[] = {5, 12, 8, 1}
Output: 13
Explanation: We can buy the first and third book with cost = 4 + 5 = 9 and pages = 5 + 8 = 13.

Input: N = 2, X = 10, price[] = {20, 30}, pages[] = {50, 100}
Output: 0
Explanation: We cannot buy any book, therefore pages = 0.

Approach: To solve the problem, follow the below idea:

The problem can be solved using Dynamic Programming. Maintain a dp[] array such that dp[i] stores the maximum number of pages we can buy such that the cost is at most i. Now, we iterate over each book and find the maximum number of pages we can buy for all costs from 0 to X. We will choose the first book and find the maximum number of pages we can buy for all costs from 0 to X. Now, when we move to the second book, dp[] already stores the maximum number of pages we can buy using only the first book. So, we iterate over all the possible costs and see whether we can buy more pages using the second book and so on.

In other words, let’s say we are at the ith book and we want to calculate whether using the ith book will increase the total number of pages. At this point, dp[] array already stores the maximum number of pages we can have using first (i-1) books for all costs ranging from 0 to X. To calculate the maximum number of pages using the ith book, we will start from cost C = X and maximize the number of pages by dp[C] = max(dp[C], pages[i] + dp[C- price[i]])

Also, we iterate cost from X to 0 and not from 0 to X as we can use a book at max once. If we move from 0 to X, then while calculating dp[C] = max(dp[C], pages[i] + dp[C- price[i]]), dp[C – price[i]] will store maximum pages we can buy including the ith book and we can end up counting the pages of ith book multiple times.

Step-by-step algorithm:

  • Maintain a dp[] array such that dp[i] stores the maximum number of pages we can buy such that the cost is at most i.
  • Iterate over each book i from 0 to (N – 1) and find the maximum number of pages we can buy using this book.
    • Iterate over all costs C starting from X to 0.
      • Check if we can purchase the ith book.
      • Update dp[C] if purchasing the ith book will increase the total number of pages.
  • After iterating over all the costs of all the books, return dp[X] as the final answer.

Below is the implementation of the algorithm:

C++
#include <bits/stdc++.h>
#define ll long long int
using namespace std;

// Function to find the maximum number of pages which we can
// have with cost <= X
ll solve(ll N, ll X, vector<ll> price, vector<ll> pages)
{
    // dp[] array such that dp[i] stores the maximum number
    // of pages we can buy such that the cost is at most i
    vector<ll> dp(X + 1, 0);

    // Iterate over all the books
    for (int i = 0; i < N; i++) {
        // Iterate over the cost from X to 0
        for (int C = X; C > 0; C--) {
            // Check if we can purchase the ith book
            if (price[i] > C)
                continue;
            // Update dp[C] if purchasing the ith book will
            // increase the total number of pages
            dp[C] = max(dp[C], pages[i] + dp[C - price[i]]);
        }
    }
    return dp[X];
}
int main()
{
    // Sample Input
    ll N = 4, X = 10;

    vector<ll> price = {4, 8, 5, 3};
    vector<ll> pages = {5, 12, 8, 1};

    cout << solve(N, X, price, pages) << endl;
}
Java
import java.util.Arrays;
import java.util.List;

public class Main {
    // Function to find the maximum number of pages which we can
    // have with cost <= X
    static long solve(int N, int X, List<Long> price, List<Long> pages) {
        // dp[] array such that dp[i] stores the maximum number
        // of pages we can buy such that the cost is at most i
        long[] dp = new long[X + 1];

        // Iterate over all the books
        for (int i = 0; i < N; i++) {
            // Iterate over the cost from X to 0
            for (int C = X; C > 0; C--) {
                // Check if we can purchase the ith book
                if (price.get(i) > C)
                    continue;
                // Update dp[C] if purchasing the ith book will
                // increase the total number of pages
                dp[C] = Math.max(dp[C], pages.get(i) + dp[C - price.get(i).intValue()]);
            }
        }
        return dp[X];
    }

    public static void main(String[] args) {
        // Sample Input
        int N = 4, X = 10;

        List<Long> price = Arrays.asList(4L, 8L, 5L, 3L);
        List<Long> pages = Arrays.asList(5L, 12L, 8L, 1L);

        System.out.println(solve(N, X, price, pages));
    }
}


// This code is contributed by shivamgupta310570
C#
using System;
using System.Collections.Generic;

public class Gfg
{
    // Function to find the maximum number of pages which we can
    // have with cost <= X
    static long Solve(int N, int X, List<long> price, List<long> pages)
    {
        // dp[] array such that dp[i] stores the maximum number
        // of pages we can buy such that the cost is at most i
        long[] dp = new long[X + 1];

        // Iterate over all the books
        for (int i = 0; i < N; i++)
        {
            // Iterate over the cost from X to 0
            for (int C = X; C > 0; C--)
            {
                // Check if we can purchase the ith book
                if (price[i] > C)
                    continue;
                // Update dp[C] if purchasing the ith book will
                // increase the total number of pages
                dp[C] = Math.Max(dp[C], pages[i] + dp[C - (int)price[i]]);
            }
        }
        return dp[X];
    }

    public static void Main(string[] args)
    {
        // Sample Input
        int N = 4, X = 10;

        List<long> price = new List<long> { 4, 8, 5, 3 };
        List<long> pages = new List<long> { 5, 12, 8, 1 };

        Console.WriteLine(Solve(N, X, price, pages));
    }
}
Javascript
function solve(N, X, price, pages) {
    // dp[] array such that dp[i] stores the maximum number
    // of the pages we can buy such that the cost is at most i
    let dp = new Array(X + 1).fill(0);
    // Iterate over all the books
    for (let i = 0; i < N; i++) {
        for (let C = X; C > 0; C--) {
            // Check if we can purchase the ith book
            if (price[i] > C) continue;
            dp[C] = Math.max(dp[C], pages[i] + dp[C - price[i]]);
        }
    }
    return dp[X];
}
// Sample Input
const N = 4;
const X = 10;
const price = [4, 8, 5, 3];
const pages = [5, 12, 8, 1];
console.log(solve(N, X, price, pages));
Python3
def solve(N, X, price, pages):
    # dp list such that dp[i] stores the maximum number
    # of pages we can buy such that the cost is at most i
    dp = [0] * (X + 1)

    # Iterate over all the books
    for i in range(N):
        # Iterate over the cost from X to price[i] in reverse
        for C in range(X, price[i] - 1, -1):
            # Update dp[C] if purchasing the ith book will
            # increase the total number of pages
            dp[C] = max(dp[C], pages[i] + dp[C - price[i]])

    return dp[X]

# Sample Input
N = 4
X = 10
price = [4, 8, 5, 3]
pages = [5, 12, 8, 1]

print(solve(N, X, price, pages))

Output
13

Time Complexity: O(N * X), where N is the number of books and X is the maximum cost of books which we can purchase.
Auxiliary Space: O(X)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads