"Introduction to Algorithms" Dynamic programming __ Algorithm

Source: Internet
Author: User

Dynamic programming This algorithm, I have been confused, perhaps because of my poor math ability, always do not have the essentials, each time learning this algorithm, always do not know the so-called state transfer equation in the end is how to derive. In fact, when I write this blog, I still do not know.

What problems can be solved by dynamic planning. The characteristic of the dynamic programming problem is the optimal substructure , a recursive structure: the problem needs to be solved by an optimal solution.

For example, the classical dynamic programming problem, the longest common subsequence (as described below), we require a longest subsequence, first this is an optimal solution, secondly, the longest common sequence of two sequences, also contains the longest public sequence of the subsequence.

Dynamic planning usually uses the following 4 steps to design an algorithm: to characterize an optimal solution by defining the value of the optimal solution recursively define the value of the optimal solution (usually using the Bottom-up method) to construct an optimal solution with the calculated information

Dynamic programming is often combined with some memo methods for recording intermediate solutions, so as to avoid repeated solution of child problems. Here are a few questions to look at:

Maximum continuous sub sequence of the longest common subsequence of steel bar cutting problem and

The problem of cutting steel rods

Given the length and price of a steel bar cutting, the best cutting scheme is obtained. And look at the following:

Length (i) 1 2 3 4 5 6 7 8 9 10
Price (PI) 1 5 8 9 10 17 17 20 24 30

Let's say we cut a steel bar with a length of 4, there are a total of the following options:
1. Do not cut, the price is 9
2.1 and 3: Price is 1 + 8 = 9
3.2 and 2: Price is 5 + 5 = 10
4.3 and 1: Price is 8 + 1 = 9
5.1、2、1: Price is 1 + 5 + 1 = 7
6.1、1、2: Price is 1 + 1 + 5 = 7
7.2、1、1: Price is 2 + 1 + 1 = 7

Can be known to split a 4-length steel bar, the optimal cutting scheme for the "scheme 2". More generally, we can make the RN to cut the length of the steel bar, you can easily get the following formula:

In this way, the code is easy to write, as follows:

#include <stdio.h> #include <stdlib.h> #include <string.h> int rodcut_recursive_down_to_up (int* p,
    int* s, int* K, int m, int n) {if (S[n] >-1) return s[n];

    int q =-1;

    if (n = = 0) return 0; for (int i = 1; I <= n; ++i) {for (int j = 1; J <= i; ++j) {int r = * (P + j) + RODCU

            T_RECURSIVE_DOWN_TO_UP (P, S, K, M, i-j);
                if (r > Q) {q = r;
                S[i] = q;
            K[i] = j;
}} return q;

    int Rodcut_recursive_up_to_down (int* p, int* s, int* K, int m, int n) {if (s[n) >-1) return s[n];

    int q =-1;

    if (n = = 0) return 0;

        for (int i = n; I >= 1;-I.) {int r = * (P + i) + Rodcut_recursive_up_to_down (p, S, K, M, n-i);
            if (r >= q) {q = r;
            S[n] = q;
        K[n] = i;
} return q; int main (VOID) {int m, n;
    scanf ("%d", &m);
        if (M!= 0) {int* p = (int*) malloc (sizeof (int) * (M + 1));
        int* s = (int*) malloc (sizeof (int) * (M + 1));
        int* k = (int*) malloc (sizeof (int) * (M + 1));
        memset (p, 0, sizeof (int) * (M + 1));

        memset (k, 0, sizeof (int) * (M + 1));
        for (int i = 1; I!= m + 1; ++i) scanf ("%d", p + i); while (scanf ("%d", &n)!= EOF) {if (n <= m) {memset (S,-1, sizeof (i
                NT) * (M + 1));

                printf ("%d:", Rodcut_recursive_up_to_down (P, S, K, M, N));
                while (n) printf ("%d", K[n]), n = n-k[n];
            printf ("\ n");
        } free (p);
        Free (k);
    Free (s);
return 0;
 }

Enter the price list, then enter the length of the cut, the output of the optimal scheme, the results are as follows:

The above offers two options, one being Top-down recursion, one is the bottom-up recursive design, from the code we can see the difference between the top down, is the first solution to the final result, and then recursive solution to the first result, and bottom-up is to solve the first result, until the last result. Longest common child sequence

The longest common subsequence is one such problem: there are two strings s and T, and the longest common subsequence of both is obtained, such as the following string:

S:abcbdab
T:bdcaba

The longest common subsequence sequence is Bdab, BCBA, Bcab and so on.

So that C[i, J] represents the longest common subsequence from I to J, we can deduce the following state transitions:

If I reach the length of the string s or J arrives at the length of the string T, the longest common subsequence is 0 if s[i] = = T[j], then the longest common subsequence is the longest common subsequence of subsequent subsequence + the current character length (1) if s[i]!= t[j], then the longest common subsequence is fetch s The larger of the subsequent longest common subsequence of the following longest common subsequence of [i] and fetch t[i] (the final result may not be s[i] or t[j])

Based on the above instructions, the code that is written is as follows:

#include <stdio.h> #include <stdlib.h> #include <string.h> int longestcommonsubsequence (char* S, Char
    * T, char** U, int ss, int ts) {if (ss = strlen (S) | | ts = = strlen (T)) return 0;
    else if (U[ss][ts]!= 0) return u[ss][ts];
        else if (s[ss] = = T[ts]) {int r = longestcommonsubsequence (S, T, U, SS + 1, TS + 1);

        U[ss][ts] = R + 1;
    return u[ss][ts];
        else {int L1 = longestcommonsubsequence (S, T, U, SS, TS + 1);

        int L2 = longestcommonsubsequence (S, T, U, SS + 1, TS);

        U[ss][ts] = (L1 >= L2? l1:l2);
    return u[ss][ts];
return 0;
    int main (void) {int m, n;
        while (scanf ("%d", &m, &n) = = 2) {char* S = (char*) malloc (sizeof (char) * (M + 1));
        char* T = (char*) malloc (sizeof (char) * (n + 1));
        char** U = (char**) malloc (sizeof (char*) * m); for (int i = 0; I!= m + 1; ++i) {U[i] = (char*) malLOC (sizeof (char) * (n + 1));
        memset (U[i], (char) 0, sizeof (char) * (n + 1));
        } scanf ("%s", s);

        scanf ("%s", T);

        printf ("%d\n\n", Longestcommonsubsequence (S, T, U, 0, 0)); for (int i = 0; I <= m. ++i) {for (int j = 0; J <= N; ++j) printf ("%d", U[i][j])
            ;
        printf ("\ n");
        int L = 0, r = 0;
                while (U[l][r]) {if (s[l] = = T[r]) {printf ("%c", s[l));
            ++l, ++r;
            }else if (u[l][r] = = u[l][r + 1]) ++r;
        else ++l;

        printf ("\ n");
        Free (S);

        Free (T);
        for (int i = 0; I!= m + 1; ++i) free (u[i]);
    Free (U);
return 0; }

The input string s and T,ss represent the starting point of the S string, TS represents the start of the T string, and U records the longest common subsequence length of the current position. The results of the output are as follows:

As you can see from the chart above, we're going to get the longest common subsequence, then we need to go through the table from "0, 0" points, we can only go to the right or down, if "I, J" point two characters s[i] and t[j] equal, then we should take the diagonal, if "I, j" = = "I, J + 1" Then we should go right, or we should go down. As shown in the above code. maximum contiguous subsequence and

Given an integer sequence, a sequence of successive sequences is obtained, making it the largest. As given in the following sequence:

-2 11-4 13-5-2, its maximum contiguous subsequence and is: 11-4 + 13 = 20

The definition sum[i] is the maximal subsequence and the following state transition equations can be deduced:

In fact, this equation, I do not know how the derivation, the front of a good understanding, but why and the current value to do compared to the larger, I really do not understand. I hope someone can give me directions. Based on the above equation, the code I write is as follows:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int maxsum = 0;
int maxsequencesum (int* num, int s, int e)
{
    if (s = = e) return
        0;

    int sum = maxsequencesum (num, S + 1, E) + num[s];

    if (Sum > 0)
    {
        if (sum > Maxsum)
        {
            maxsum = sum;
            return sum;
        }

        return sum;
    }
    return 0;
}

int main (void)
{
    int m;

    while (scanf ("%d", &m)!= EOF)
    {
        int* n = (int*) malloc (sizeof (int) * m);

        for (int i = 0; I!= m; ++i)
            scanf ("%d", n + i);

        maxsum = 0;
        Maxsequencesum (n, 0, m);
        printf ("%d\n", maxsum);
        Free (n);
    }

    return 0;
}

The output of the program, as shown in the following illustration:

There is also a simpler way of writing:

int maxsumsubsequence (const int a[], int N)
{
    int thissum,maxsum,j;
    Thissum = Maxsum =0;
    for (j = 0;j < n;j++)
    {
        thissum + = a[j];

        if (Thissum > Maxsum)
            maxsum = thissum;
        else if (Thissum < 0)
            thissum = 0; 
    }
    return maxsum; 
}

This piece of code is copied online, I did not expect to write this at first. My level still has a lot of room for improvement.

The above code I personally prepared, by my test is basically correct, perhaps the way of writing and online spread different, if there are mistakes, please criticize.

Dynamic programming This algorithm is really very practical, unfortunately, I am still half know half solution, the reason for the thick skin to write this article, but also hope that one day can be a high man happened to see this clumsy Bowen, pointing to me this hard self-study, no friend consulting the younger brother, thank you first.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.