The Beauty of Programming

Keywords: Java Programming

The Beauty of Programming has an interesting title: the problem of buying books. The title is as follows:
There are five volumes of Harry Potter Paperback Series on the shelf. Suppose that each volume is sold separately for 8 euros. If readers buy two different volumes at a time, they can deduct 5% of the cost, and three volumes are more. Assuming that the specific discount is as follows:

2. Discount 5%

3) 10% discount

4) Discount of 20%

25% discount
       
An algorithm is designed to calculate the lowest price of a batch of books purchased by the reader.
The author first tries to use greedy algorithm to analyze the problem, and finally draws the conclusion that it is not feasible to use greedy strategy to solve this problem, and then uses dynamic programming algorithm to solve it. The general idea is:
Use (X1,X2,X3,X4,X5) to represent the number of volumes purchased, and F (X1,X2,X3,X4,X5) to represent the lowest price. And satisfy X1 <= X2 <= X3 <= X4 <= X5
Can be obtained:

F(X1,X2,X3,X4,X5)  = 0                                                // if (X1 = X2 = X3 = X4 = X5 = 0)
                       = min{
                            5*8*(1-25%) +F(X1-1,X2-1,X3-1,X4-1,X5-1)  // if (X1 > 0)
                            4*8*(1-20%) +F(X1,X2-1,X3-1,X4-1,X5-1)    // if (X2 > 0)
                            3*8*(1-10%) +F(X1,X2,X3-1,X4-1,X5-1)      // if (X3 > 0)
                            2*8*(1-5%) +F(X1,X2,X3,X4-1,X5-1)         // if (X4 > 0)
                            8 +F(X1,X2,X3,X4,X5-1)                    // if (X5 > 0)
                         }   

Let's analyze the title, "The lowest price of a batch of books purchased by readers" in two scenarios: one is that the number of books in each batch is fixed; the other is that the number of books in each batch is uncertain. We can only know how many books there are in the batch, and then calculate the lowest price of all combinations based on the total. Obviously, the algorithm given by the author aims at the former, if the latter, how to design the algorithm?
We use N to represent the total number of books, F(N) to represent the price of N books, and meet N > 0, then there are five combinations as follows:
1. Among the books purchased, there is a single volume that is not discounted. Examples: 11 books, 5 + 5 + 1 combination. List the formulas:

F(N) = F(N - 1) + 8                                                       // if (N > 0)

2. Among the books purchased, two of them received a 5% discount. Examples: 11 books, 5 + 4 + 2 combination. List the formulas:

F(N) = F(N - 2) + 8 × 2 × 95%                                             // if (N > 1)

3. Among the books purchased, three of them enjoy a 10% discount. Examples: 11 books, 4 + 4 + 3 combination. List the formulas:

F(N) = F(N - 3) + 8 × 3 × 90%                                             // if (N > 2)

4. Among the books purchased, four of them enjoy a 20% discount. Examples: 11 books, 5 + 4 + 2 combination. List the formulas:

F(N) = F(N - 4) + 8 × 4 × 80%                                             // if (N > 3)

5. Among the books purchased, five of them enjoy a 25% discount. Examples: 11 books, 5 + 4 + 2 combination. List the formulas:

F(N) = F(N - 5) + 8 × 5 × 75%                                             // if (N > 4)

Can be obtained:

min(F(N)) = min{
                F(N - 1) + 8                                              // if (N > 0)
                F(N - 2) + 8 × 2 × 95%                                    // if (N > 1)
                F(N - 3) + 8 × 3 × 90%                                    // if (N > 2)
                F(N - 4) + 8 × 4 × 80%                                    // if (N > 3)
                F(N - 5) + 8 × 5 × 75%                                    // if (N > 4)
            }

The source code is as follows:

package algorith.books;

import java.util.Scanner;

public class Books1 {

    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);

        while (scanner.hasNext()) {
            int n = scanner.nextInt();
            System.out.println("the min price is " + price(n));
        }
    }

    public static double price(int n){
        double min_p = 0;

        if (n==0)
            return 0;

        min_p = price(n-1) + 8;

        if (n >= 2) {
            double temp = price(n-2)+8*2*0.95;
            if (min_p > temp)
                min_p = temp;
        }

        if (n >= 3) {
            double temp = price(n-3)+8*3*0.9;
            if (min_p > temp)
                min_p = temp;
        }

        if (n >= 4) {
            double temp = price(n-4)+8*4*0.8;
            if (min_p > temp)
                min_p = temp;
        }

        if (n >= 5) {
            double temp = price(n-5)+8*5*0.75;
            if (min_p > temp)
                min_p = temp;
        }

        return min_p;
    }

}

The results are as follows:

1
the min price is 8.0
2
the min price is 15.2
3
the min price is 21.6
4
the min price is 25.6
5
the min price is 30.0
6
the min price is 38.0
7
the min price is 45.2
8
the min price is 51.2
9
the min price is 55.6
10
the min price is 60.0

Posted by warmwind on Fri, 11 Oct 2019 09:02:11 -0700