Open In App

Maximizing Readability-Coefficient for Book Printing

Last Updated : 07 Dec, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

A book publisher collected data on the readability level of his n books. Book publisher can print any book in 1 unit of time. Readability-Coefficient of a book is defined as the time taken to print that book including previous books multiplied by its readability level, i.e. total_time * readability[i], the task is to return the maximum sum of Readability-Coefficient that the publisher can obtain after books are printed, you can keep the books even if its readability level is negative, so as to get the maximum value of total Readability-Coefficient. Books can be printed in any order and the publisher can discard some books to get this maximum value.

Examples:

Input: readability: [-1, -7, 3]
Output: 5
Explanation: Here we could have taken -1 and -7 but taking both of them reduces the total Readability-Coefficient , as -7*1 + -1*2 + 3*3 = 0 , we can neglect -7 readability and -1 readability but now the total Readability-Coefficient becomes 3*1 = 3, hence we keep -1*1 + 3*2 = 5 as the total Readability-Coefficient, which is the maximum value.

Input: readability: [-1, -3, -9]
Output: 0
Explanation: People do not like the books. No book is published.

Approach: To solve the problem follow the below idea:

The idea behind this is to Take or Not Take the current Book with certain readability, and simultaneously keep incrementing the counter to keep track of the time.

Steps to solve the problem:

  • The solver function is designed to recursively explore the possibilities and calculate the maximum readability.
  • It takes three parameters: readability (vector of integers), i (current index), and counter (a counter to keep track of the time).
  • Base Cases:
    • If i exceeds the size of the readability vector, it returns 0, as there are no more elements to consider.
    • If the value for the current i and counter combination has already been calculated (dp[i][counter] is not -1), it returns the memoized result.
  • Recursive Cases:
    • It considers two possibilities: either taking the current readability or not taking it.
    • take is calculated by multiplying the readability at index i with the counter and recursively calling solver for the next index (i+1) and an incremented counter (counter+1).
    • nottake is calculated by directly calling solver for the next index (i+1) with the same counter.
  • Sorting:
    • The readability vector is sorted before the process starts.
  • Modulo Operation:The final result is taken modulo 1000000007 to ensure that the result remains within the desired range.

Below is the implementation of the above approach:

C++14




// C++ code for the above approach:
#include <bits/stdc++.h>
using namespace std;
 
// Global 2D array for memoization
int dp[1001][1001];
 
// Recursive function to find maximum readability
int solver(vector<int>& readability, int i, int counter)
{
    // Base case: If index exceeds the
    // size of 'readability'
    if (i >= readability.size()) {
        return 0;
    }
 
    // If the result for current 'i' and 'counter'
    // combination is already calculated
    if (dp[i][counter] != -1)
        return dp[i][counter];
 
    // Calculate 'take' and 'nottake'
    // options recursively
    int take = readability[i] * counter
               + solver(readability, i + 1, counter + 1);
    int nottake = solver(readability, i + 1, counter);
 
    // Store the result in 'dp' array and return
    // the maximum value
    return dp[i][counter] = max(take, nottake) % 1000000007;
}
 
// Function to find maximum readability
int maxreadability(vector<int>& readability)
{
    // Sort the 'readability' vector
    sort(readability.begin(), readability.end());
 
    // Initialize 'dp' array with -1
    // for memoization
    memset(dp, -1, sizeof(dp));
 
    // Start the recursion from index 0
    // with counter 1
    return solver(readability, 0, 1);
}
 
// Drivers code
int main()
{
 
    // Example 'readability' vector
    vector<int> readability = { -1, -7, -3, 5, -9 };
 
    // Call the 'maxreadability' function and
    // print the result
    cout << maxreadability(readability);
    return 0;
}


Java




import java.util.Arrays;
import java.util.Vector;
 
public class Main {
 
    // Global 2D array for memoization
    static int[][] dp = new int[1001][1001];
 
    public static void main(String[] args) {
        // Example 'readability' vector
        Vector<Integer> readability = new Vector<>(Arrays.asList(-1, -7, -3, 5, -9));
 
        // Sort the 'readability' vector
        readability.sort(null);
 
        // Initialize 'dp' array with -1 for memoization
        for (int[] row : dp) {
            Arrays.fill(row, -1);
        }
 
        // Call the 'maxreadability' function and print the result
        System.out.println(maxreadability(readability));
    }
 
    // Recursive function to find maximum readability
    public static int solver(Vector<Integer> readability, int i, int counter) {
        // Base case: If index exceeds the size of 'readability'
        if (i >= readability.size()) {
            return 0;
        }
 
        // If the result for the current 'i' and 'counter' combination is already calculated
        if (dp[i][counter] != -1) {
            return dp[i][counter];
        }
 
        // Calculate 'take' and 'nottake' options recursively
        int take = readability.get(i) * counter + solver(readability, i + 1, counter + 1);
        int nottake = solver(readability, i + 1, counter);
 
        // Store the result in 'dp' array and return the maximum value
        return dp[i][counter] = Math.max(take, nottake) % 1000000007;
    }
 
    // Function to find maximum readability
    public static int maxreadability(Vector<Integer> readability) {
        // Start the recursion from index 0 with counter 1
        return solver(readability, 0, 1);
    }
}


Python3




# Python 3 code for the above approach
 
# Global 2D array for memoization
dp = [[-1] * 1001 for _ in range(1001)]
 
# Recursive function to find maximum readability
def solver(readability, i, counter):
    # Base case: If index exceeds the size of 'readability'
    if i >= len(readability):
        return 0
 
    # If the result for the current 'i' and 'counter' combination is already calculated
    if dp[i][counter] != -1:
        return dp[i][counter]
 
    # Calculate 'take' and 'nottake' options recursively
    take = readability[i] * counter + solver(readability, i + 1, counter + 1)
    nottake = solver(readability, i + 1, counter)
 
    # Store the result in 'dp' array and return the maximum value
    dp[i][counter] = max(take, nottake) % 1000000007
    return dp[i][counter]
 
# Function to find maximum readability
def maxreadability(readability):
    # Start the recursion from index 0 with counter 1
    return solver(readability, 0, 1)
 
 
# Driver code
if __name__ == "__main__":
    # Example 'readability' list
    readability = [-1, -7, -3, 5, -9]
 
    # Sort the 'readability' list
    readability.sort()
 
    # Call the 'maxreadability' function and print the result
    print(maxreadability(readability))
     
# This code is contributed by Rohit Singh


C#




// C# code for the above approach
 
using System;
using System.Collections.Generic;
 
class GFG {
    // Global 2D array for memoization
    static int[, ] dp = new int[1001, 1001];
 
    // Recursive function to find maximum readability
    public static int solver(List<int> readability, int i,
                             int counter)
    {
        // Base case: If index exceeds the size of
        // 'readability'
        if (i >= readability.Count) {
            return 0;
        }
 
        // If the result for the current 'i' and 'counter'
        // combination is already calculated
        if (dp[i, counter] != -1) {
            return dp[i, counter];
        }
 
        // Calculate 'take' and 'nottake' options
        // recursively
        int take
            = readability[i] * counter
              + solver(readability, i + 1, counter + 1);
        int nottake = solver(readability, i + 1, counter);
 
        // Store the result in 'dp' array and return the
        // maximum value
        return dp[i, counter]
            = Math.Max(take, nottake) % 1000000007;
    }
 
    // Function to find maximum readability
    public static int maxreadability(List<int> readability)
    {
        // Start the recursion from index 0 with counter 1
        return solver(readability, 0, 1);
    }
      // Driver code
    public static void Main()
    {
        // Example 'readability' list
        List<int> readability
            = new List<int>{ -1, -7, -3, 5, -9 };
 
        // Sort the 'readability' list
        readability.Sort();
 
        // Initialize 'dp' array with -1 for memoization
        for (int i = 0; i < 1001; i++) {
            for (int j = 0; j < 1001; j++) {
                dp[i, j] = -1;
            }
        }
 
        // Call the 'maxreadability' function and print the
        // result
        Console.WriteLine(maxreadability(readability));
    }
}
 
// This code is contributed by ragul21


Javascript




// Javascript code for the above approach:
 
// Global 2D array for memoization
const dp = new Array(1001);
for (let i = 0; i < 1001; i++) {
    // Initialize 'dp' array with -1
    // for memoization
    dp[i] = new Array(1001).fill(-1);
}
 
// Recursive function to find maximum readability
function solver(readability, i, counter) {
    // Base case: If index exceeds the
    // size of 'readability'
    if (i >= readability.length) {
        return 0;
    }
 
    // If the result for current 'i' and 'counter'
    // combination is already calculated
    if (dp[i][counter] != -1)
        return dp[i][counter];
 
    // Calculate 'take' and 'nottake'
    // options recursively
    let take = readability[i] * counter +
        solver(readability, i + 1, counter + 1);
    let nottake = solver(readability, i + 1, counter);
 
    // Store the result in 'dp' array and return
    // the maximum value
    dp[i][counter] = Math.max(take, nottake) % 1000000007;
    return dp[i][counter];
}
 
// Function to find maximum readability
function maxreadability(readability) {
    // Sort the 'readability' array
    readability.sort((a, b) => a - b);
 
    // Start the recursion from index 0
    // with counter 1
    return solver(readability, 0, 1);
}
 
// Drivers code
// Example 'readability' array
const readability = [-1, -7, -3, 5, -9]
 
// Call the 'maxreadability' function and
// print the result
console.log(maxreadability(readability))
 
// This code is contributed by ragul21


Output

10








Time Complexity: O(n^2). where n is the size of the ‘readability‘ vector
Auxiliary Space: O(n^2) .



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads