Talking about dynamic programming from the least amount of currency exchanged

topic

Given an array arr, all values ​​in arr are positive and non-repeating. Each value represents a currency with a face value, and any currency can be used for each currency. Given an integer aim representing the amount of money to be found, find the minimum number of currencies that make up the aim. For example arr=[5, 2, 3], aim=20, return 4

After seeing this question, if we don't know dynamic programming, how can we answer it?

Mashup Resolution Process

This question was asked by a child, and his answer was very interesting. After careful analysis, it turned out to be a mashup of various algorithms.

  1. Sort coins by size first
  2. Then use aim to withdraw the maximum amount of coins
  3. Continue to find the second largest coin for the remainder
  4. If not, return the largest coin to the remainder and continue the above operation
    . Some people say that the above process is a brute force cracking, but it is not when you think about it carefully. Since the solution is to solve the minimum number of coins, he prioritizes the sorting, hoping to fill the most with the largest coins. This is a typical greedy method. After taking the remainder, if there is no result, return the largest coin to the remainder to continue the above operation. Here is the backtracking. The above method looks very good, and it is also the general idea of ​​​​finding change, but this idea is not described further below. Since not every piece of money has to participate in the change, the method of backtracking itself is wrong. For example, the change to be found is 17, and our money is sorted to 532, according to the above idea.
  5. 17%5 take the remainder as 2 and the quantity as 3 aim:2 count:3
  6. 3 is not satisfied, start backtracking aim: 7 count: 2
  7. 7%3 The remainder is 1, the quantity is 2 aim:1 count:4 …………
  8. The final result is 2 pieces of 5 yuan, 1 piece of 3 yuan, and 2 pieces of 2 pieces. The result is 5. Everyone finds that something is wrong. There are 2 coins, so you should take 2 directly. The result is 4 and it is over. But the program actually started backtracking. Then the children began to improve, and when the current coins were not satisfied, they continued to go down, and then they started backtracking when they reached the end. This can get the correct answer, but it's the same thing as brute force.

empirical solution

Empirical solutions are widely used when looking for money. With the growth of time, the experience of the salesperson to find money is also enriched. Slowly I have the experience of looking for 5 yuan, 7 yuan, 9 yuan, 10 yuan and so on. When it comes to looking for 12 yuan, you can make decisions based on 10 yuan experience and 9 yuan experience.

  1. Existing experience, 5 yuan experience is 5 yuan is 1, 10 yuan is 2. 3 yuan experience 9 yuan is 3. 2 yuan experience is 7 yuan is 2.
  2. Start looking for $12 now
  3. The case of 5 yuan is impossible to find
  4. 3 yuan can rely on the experience of 9 yuan can be solved by adding a 3 yuan, the result is 4
  5. 2 yuan is to rely on the experience of 7 yuan, add a 5 yuan, the result is 3
  6. The least comparison is 3

Charts describe experiences

Describe the problem as follows

| - | 5 | 3 | 2 |
|:---|: ---:|:---:|:---:|
|2 |-|-|1|

|3 | -|1|1|

|4|-|-|2|

|5|1|1|1|

|6|-|2|2|

|7|-|-|2|

……

The rules of the above diagram are from left to right, from top to bottom. The grid for each experience represents the minimum amount occupied. Experience is from left to right, such as the composition of 3 yuan, when the experience reaches 2 yuan, the 2-tuple is not 3 yuan, it is originally -, but the first 3 yuan can be, in contrast, the minimum is 1.5 yuan The composition of 5 yuan itself can be composed, it is 1, 3 tuples cannot be formed, but it can be taken from 5 yuan, or 1, when it reaches 2 yuan, 2 plus (5-2), the amount of money The experience of 3 is 1, and the amount of money is 2, but it is larger than the 1 passed in earlier, so fill in 1. This graph is represented by dp, and the comparison sources for each grid are dp[i-1][j] and dp[i][j-money]+1. Pick the smallest answer.

code description

    public static int getCount(Integer[] arr, int aim) {
        //图表的构建
        int[][] dp = new int[arr.length][aim + 1];
        for (int i = 1; i <= aim; i++) {
            for (int j = 0; j < arr.length; j++) {
                if (i - arr[j] < 0) {
                    //把无解的设置为int的最大值
                    dp[j][i] = Integer.MAX_VALUE;
                } else {
                    //获取当前列前面的经验
                    int preNum = dp[j][i - arr[j]];
                    if (j > 0) {
                        //当前列和前一列的比较,取最小值
                        dp[j][i] = Integer.min(preNum == Integer.MAX_VALUE ? Integer.MAX_VALUE : preNum + 1, dp[j - 1][i]);
                    } else {
                        dp[j][i] = preNum == Integer.MAX_VALUE ? Integer.MAX_VALUE : preNum + 1;
                    }

                }
            }
        }
        return dp[arr.length - 1][aim];
    }

dynamic programming

The above empirical description is the dynamic programming method. Many algorithm books explain this algorithm very deep (in fact, he is the most difficult one in the basic algorithm), we must find a formula to express it, and we must be able to summarize and draw the above diagram. This is the expression in many books, but it is not very clear. It is difficult to summarize the formula by simply relying on the topic. Therefore, the method of first drawing the picture and then formulating the formula is proposed, and it is well understood. Each line actually expresses the meaning of the least cost from left to right. The specific formula summary can be viewed slowly in the process of drawing. Once the drawing is completed, with the coordinates, it is easy to find the law, which is much better than fantasy. Each row only needs to pay attention to the result of each row. The first few columns do not need experience at all, so the process of solving the problem is the embodiment of experience. If you think this topic is easy to understand, try another topic. https://my.oschina.net/xpbob/blog/759137 I answered this question in the most book-like way. You can compare it to see if today's idea makes it easier for you to use dynamic programming.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325470371&siteId=291194637