Simple violence to dp optimization (introductory article)

In the last article, we mentioned that when encountering a problem, first write a stupid method according to the definition, find out the dependencies (some problems are not very simple, you need to summarize the relationship yourself), and then optimize it. Below, we pass a few methods. In terms of classic, relatively simple two-dimensional topics to explain, the so-called two-dimensional, that is, there are two parameters that represent the state.

As a classic problem, the backpack problem is a very basic problem . It is old-fashioned, but it is helpful for newbies to develop thinking habits and familiarize themselves with the thinking process. Although some problem routines are very mature, I still want to think about myself at that time. Think about it and write it. When you think about the solution and find it is the same as the standard problem solution, it feels really good. As a novice, I think, maybe this is its charm. (of course more frustration)

In the new stage, our so-called classical knapsack problem ensures that all quantized data are positive integers, which is a special integer programming problem . Ask Baidu Backpack to give nine lectures. There are too many explanations, so I will not write them.

 

Also, in the future, I will write with heart and try to express it clearly in as few words as possible, and the language will be more formal in the future.

Ok, start to explain according to the question:

The first novel topic

Given an array arr, all values ​​in arr are positive and non-repeating. Each value represents a currency of denomination, and any currency of each denomination can be used. Given an integer aim representing the amount of money to be found, find the minimum number of currencies that make up aim.

  [example]

  arr=[5,2,3],  aim=20。

  4 pieces of 5 yuan can form 20 yuan, other money-seeking schemes must use more pieces of currency, return 4.

arr=[5,2,3],  aim=0。

  0 yuan can be formed without any currency, and 0 is returned.

  arr=[3,5],aim=2。

  It is impossible to form 2 yuan at all. If the money cannot be found, it will return -1 by default.

(If you want to be greedy, be greedy, I'm not greedy anyway)

The definition f(a,b) represents the face value of a and the previous currency, and the minimum number of sheets to form b yuan. Then f(arr[-1], aim) is the answer we want. Now analyze, how to deduce the result through the previous state? For the currency arr[-1], we can use none, the minimum number of cards is actually f(arr[-2], aim), we can also use one arr[-1], the minimum number of cards may be f(arr[-2], aim-arr[-1])+1 (use the previous money to form aim-arr[-1] dollars, and then add an arr[-1]), in the same way, we can Use two arr[-1], or more, until the next one exceeds aim. So we should choose the smallest of all cases,

Inductive expression:

f(a,b)=min(f(arr[a-1],b-k*arr[a])+k),k>=0,且b-k*arr[a]>=0

Of course, as mentioned before, we will have a lot of repeated calculations with direct recursion, so we need to write down the previous results for us to use. There are two parameters representing the current state, so a two-dimensional table is generated.

l=[[0 for i in range(len(arr))] for i in range(aim+1)]

Blow a wave of py here, the left is the element to be generated, the right is a loop, and the few-dimensional table is generated in one line.

Let's see, who is f(arr[a],b) related to? It is related to the many left elements of the previous line, that is, the line of arr[a-1].

So determine the order of playing the table, from top to bottom, from left to right, play the table, one by one, l[a][b]=min(f(a-1,bk*arr[a])+k), Introduce l[a][b] in turn, and the lower right corner is the answer.

 

However, there are still a lot of repeated calculations. Our l[a][b-arr[a]] is actually the minimum value based on the elements to the left of l[a-1][b], so l[ a][b]=min(l[a][b-arr[a]],l[a-1][b]+1). So far, the time has been optimized to strictly o(a*b), the space is o(a*b), and the space can also be optimized to o(min(a,b)). The next topic is about the compression method.

The second new topic

Given a matrix composed of numbers, the initial is in the upper left corner, and it is required to move down or to the right each time. The path sum is the sum of all the numbers passed to find the smallest possible path sum.

1  3  5  9

8  1  3  4

5  0  6  1

8  8  4  0

path: 1 3 1 0 6 1 0 path and min, return 12

Generate a two-dimensional table DP of the same size as the matrix to record the current minimum path and

(The time complexity of violence will not be analyzed in the future)

For the general position i, j, only the two positions i-1, j and i, j-1 can go here in one step, so

DP[i,j]=min(DP[i,j-1],DP[i-1,j])+L[i,j]

Compression: We found that, in addition to the number at this position, DP[i,j] is only related to the left and upper values ​​in the DP table, so a one-dimensional table with the length of the smaller side of the matrix can be generated, using two layers of loops. Pay attention to the order, play the table from left to right, only in this way, the element on the left is the one that has been updated, and it is the element on the left of the row.

The leftmost DP value is directly accumulated, other positions

For i 0 to altitude:

    For j 0 to width

DP[j]=min(DP[j-1],DP[j])+L[i,j]

Time does not change, space is optimized to o (smaller side length)

The third cute new question

The question stem is the same as the first question, please return all the ways to repay the money.

After one or two questions, you should be able to do it yourself.

Then give a py code directly, don't talk about it. .
Simple, Baidu pieced together the denomination. .

 


n=int(input())
dp=[0]*(n+1)
dp[0]=1
tmp=[1,5,10,20,50,100]
for kk in tmp:
    for i in range(kk,n+1):
        dp[i]+=dp[i-kk]
print(dp[n])

Well, next time I can finally write something fun. . happy
big guy don't spray

Let me know if there are any mistakes, thank you

Guess you like

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