Dynamic Planning-Introduction

Dynamic programming

Wikipedia defines dynamic programming as follows:

dynamic programming is a method for solving a complex problem by breaking it down into a collection of simpler subproblems, solving each of those subproblems just once, and storing their solutions.
Ref: Dynamic programming

In other words, dynamic programming must have the following three characteristics:

  1. Decompose the original problem into several similar sub-problems. (Emphasis on "similar sub-problems")
  2. All sub-problems need to be resolved only once. (Emphasis on "only resolve once")
  3. Store the solution to the subproblem. (Emphasis on "save")

So how to judge whether a problem can be solved by dynamic programming?

If the principle of optimality for solving the problem holds, it can be solved by dynamic programming

Regardless of the initial state and initial decision of the process, the remaining decisions must form an optimal decision sequence relative to the state generated by the initial decision. Let's learn dynamic programming through a few examples.

1. The number tower problem

Problem Description

        7 
      3   8 
    8   1   0 
  2   7   4   4 
4   5   2   6   5

There is an r-row counting tower with several numbers on it. Q. From the highest point to the bottom of the tower, what is the largest sum of the numbers passed in all paths?
As shown in the figure above, it is a 5-row counting tower, in which the path of 7-3-8-7-5 passes through the number and the maximum is 30.

Solution ideas

In the face of the number tower problem, it is obviously not feasible to use the greedy algorithm. For example, if the greedy algorithm is used, then the path chosen should be 7-8-1-7-1-5, and the number after the number is only 28, and Not the biggest. With the deep search DFS, it is easy to calculate the time complexity as O (2N-1) (because each number has two options of lower left and lower right), the more the number of lines, the more must be timed out.

Therefore, the dynamic programming algorithm is needed for the data tower problem.

① We can traverse from top to bottom.

It can be found that if you want to pass a number, you can only reach it from the number in the upper left corner or the upper right corner.

So obviously, when passing any number A, the largest number that the path passes through is the number B in the upper left of the number A and the number C in the upper right. The largest and largest of the numbers can be reached That one, plus that number A.

Therefore, the state transition equation is: [official]

Where i, j represent the number of rows and columns, dp represents the maximum sum of storage, and num represents the number at the position.

[official]Indicates the upper left corner and [official]indicates the upper right corner.

To illustrate with an example: when passing the number 1 in the third row, we first look at the maximum sum of the number 3 in the upper left corner and the number 8 in the upper right corner. 3 obviously has only 7-3 path, so the maximum sum is 10; 8 obviously also has only 7-8 path, the maximum sum is 15; the larger of the two is 15, so the maximum sum that can be reached after 1 is 15 + 1 = 16.

This traverses step by step, and finally the maximum sum that can be reached after passing through each position is obtained, as long as the maximum value is found from the bottom row and output.

② We can also traverse from bottom to top.

No matter whether a path goes from top to bottom or from bottom to top, the number and the number it passes are the same, so this question can be turned into a demand-the sum of the largest number that passes from the bottom to the highest point.

The writing method is the same as the sequential traversal, except that when the state transitions, the max is taken from the lower left corner and the lower right corner of the number. Compared with sequential traversal, the advantage of writing in reverse order traversal is that the process of finding the last line max in the last step is less, and the value stored at the highest point can be directly output.

Code

#include <stdio.h>
#include <algorithm>
using namespace std;//这里以顺序遍历为例
int num[1005][1005];//用于储存数塔每个位置的数字
int dp[1005][1005];//用于储存经过数塔每个位置所能达到的最大和
int main()
{
    int r;
    scanf("%d",&r);//输入数塔行数
    for(int i=1;i<=r;i++)
        for(int j=1;j<=i;j++)
            scanf("%d",&num[i][j]);
    //输入数塔数据,注意i和j要从1开始,防止数组越界
    for(int i=1;i<=r;i++)//共计r行
        for(int j=1;j<=i;j++)//每行有j个数字
            dp[i][j]=max(dp[i-1][j],dp[i-1][j-1])+num[i][j];
    //经过该数字的最大和,为左上角和右上角中的max,再加上该数字
    int ans=0;
    for(int i=1;i<=r;i++)
        ans=max(ans,dp[r][i]);//从最后一行中找到最大数
    printf("%d\n",ans);//就是答案
    return 0;
}

Guess you like

Origin www.cnblogs.com/fluxation/p/12693486.html