--01 packet DP the primary issue, the longest common subsequence, completely backpack bag value 01, and the multiple portions, increase the longest sequence, dividing the number of problems, the number of combinations multiset

  When most beginners to start learning dp contact is often a lot of dp knapsack problem, then we are here to wish to discuss common problems dp several backpack;

 

  A knapsack problem, 0-1 knapsack problem

    A realization, return max (rec (i + 1, j), rec (i + 1, j - cost [i]) + value [i]); // i-th items of the option is not selected or

    Memory of this is due to the realization dp array a generated: dp [i] [j]: First, note that i indicates the i-th items, j represents the value of the remaining, then the entire dp representation is i items to the last item n - 1 is capable of generating the maximum value of his;

        Similarly, we use the recursive relationship, we can know

      dp[ i ] [ j ] = max ( dp[ i + 1] [ j ] ,  dp[ i + 1] [ j - w[ i ] ] + value [ i ]) ; 

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
#include <algorithm>
#include <vector>
#include <queue>
#include <list>
#include <map>
#include <stack>
#include <set>
#include <string>

using namespace std;
const int MAX_N = 1010;
const int MAX_W = 1010;
int dp[MAX_N][MAX_W];
int N, W;
int w[MAX_N], value[MAX_N];
int main()
{
    cin>>N>>W;
    for(int i = 0; i < N; i++)  cin>>w[i]>>value[i];
    dp[N][0] = 0;
    fill(dp[N], dp[N] + W, 0);
    for(int i = N - 1; i >= 0; i--){
        for(int j = 0; j <= W; j++){
            if(j < w[i])
                dp[i][j] = dp[i+1][j];
            else
                dp[i][j] = max(dp[i+1][j], dp[i+1][j-w[i]] + value[i]);
        }
    }
    return 0;
}

  If you feel a little uncomfortable so against the derivation of words, we can simply for a change dp array definition, we use from the original dp [i] [j] by the i to the end; likewise dp [i + 1] [j ] we can be set from 0 to i i + 1 Ge this article, but you need to pay attention;

 

  

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
#include <algorithm>
#include <vector>
#include <queue>
#include <list>
#include <map>
#include <stack>
#include <set>
#include <string>

using namespace std;
const int MAX_N = 1010;
const int MAX_W = 1010;
int dp[MAX_N][MAX_W];
int N, W;
int w[MAX_N], value[MAX_N];
int main()
{
    cin>>N>>W;
    for(int i = 0; i < N; i++)  cin>>w[i]>>value[i];
    fill(dp[0], dp[0] + W, 0);
    for(int i = 0; i < N; i++){
        for(int j = 0; j <= W; j++){
            if(j < w[i])
                dp[i+1][j] = dp[i][j];
            else
                dp[i+1][j] = max(dp[i][j], dp[i][j-w[i]] + value[i]);
        }
    }
   printf("THE RESULT : %d\n", dp[N][W]);
return 0; }

   Longest common subsequence problem:

  So we can all look to catch up with the problem , and Lenovo dp knapsack problem i + i + 1 instead of setting 1 clever, thus preventing the subject of the next array bounds!

    dp [i + 1] [j + 1]: This refers s0 [i] Questions s0 [j] when the two elements of the two strings, his current longest common subsequence length

  Then we use the method to catch the problem to find the relationship between the upper and lower levels:

  dp [i + 1] [j + 1] = dp [i] [j] + 1; if and only if this is s0 [i] = s1 [j];

  When the time does not satisfy this equation

  dp [i + 1] [j + 1] = max (dp [i + 1] [j], dp [i] [j +1]) // This is because the last two are not equal, not be used at the same time, so we have to delete a scale, you can also reduce the problem!

 

  

#include <iostream>
#include <cstring>
#include <bits/stdc++.h>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <cctype>
#include <cmath>
using namespace std;
const int MAX_S = 1010;
char s0[MAX_S], s1[MAX_S];
int len1, len0;
int dp[MAX_S][MAX_S];
int main()
{
    cin>>s0>>s1;=
    len0 strlen(s0);
    len1 = strlen(s1);
    fill(dp[0], dp[0] + MAX_S, 0);
    for(int i = 0; i < len0; i++){
        for(int j = 0; j < len1; j++){
            if(s0[i] == s1[j]){
                dp[i+1][j+1] = dp[i][j] + 1;
            }
            else{
                dp[i+1][j+1] = max(dp[i+1][j], dp[i][j+1]);
            }
        }
    }
    printf("THE ANSWER IS THAT : %d\n", dp[len0][len1]);
    return 0;
}

/*
abcd
becd


*/

 

And finally to the brothers' favorite full knapsack problem : the

    So for this backpack similar to 0 1, but in an infinite number of situations, how we recursive it?

    The simplest, easiest to think of is modeled on our 01 backpack is solved

    In order to maintain the forward direction, our dp [i + 1] [j] represents the first i products in the process, the result is 0 - Maximum Value kinds of goods after i reasonable choice! 

  Therefore, we have dp [i + 1] [j] = max (dp [i] [j - k * w [i]] + k * value [i]) Note that this is to ensure that the subscript index is greater than zero, and our k is a natural number;

  But have to say that this algorithm complexity is too high, then how do we further simplify? ?  

  dp[ i + 1] [ j ] = max(dp [ i ] [ j ], dp[ i + 1] [ j - w[ i ]] + value[ i ]);

  Note that the call this formula when we must note that the subscript index is greater than zero, and initialize

   dp[ i + 1] [ j ] =  max(dp [ i ] [ j - k * w[ i ] ] + k * value[ i ] )  k >= 0;

        = max(dp[ i ] [ j ] , dp [ i ] [ j - k * w[ i ] ] + k * value[ i ] )  k >= 1;

        = max(dp[ i ] [ j ] , dp [ i ] [ j  - w[ i ] - k * w[ i ] ] + k * value[ i ]  + value[ i ])  k >= 0;

        = max(dp[ i ] [ j ] , dp [ i  + 1 ] [ j  - w[ i ] ]  + value[ i ]);  

  Then this is a good proof of it.

 

 

 

 

 

 

    

 

Guess you like

Origin www.cnblogs.com/lucky-light/p/11504534.html