July Qing North Academy Training Day 5

Today is Zhonghao Xi teacher to teach ~

Dynamic Programming

Three kinds of Dynamic Programming Method:

1. recurrence;

2. recursion;

3. The memory of;

 

for example:

Fibonacci number: 0,1,1,2,3,5,8 ......

, And F n =, and F n-the 1 +,, and F n-the 2

 

1. We direct recursion, get their own results with the results of others:

#include<iostream>

using namespace std;

int main()
{
    cin >> n;
    f[0]=0;f[1]=1;
    
    for (int a=2;a<=n;a++)
        f[a] = f[a-1] + f[a-2];
    cout << f[n];
    return 0;
}

 

 

2. Use the results to count his other results:

#include<iostream>

using namespace std;

int main()
{
    cin >> n;
    f[0]=0;f[1]=1;for (int a=0;a<n;a++)
    {
        f[a+1] += f[a];
        f[a+2] += f[a];
    }
    
    return 0;
}

When dynamic programming, any question can be used both methods to write;

But there is a different problem worse of the two methods have advantages, so we will have two methods.

 

3. Memory search:

We can easily find the process of seeking Fibonacci series deed is recursive process, then you can write about recursive code:

Since our Fibonacci that this method is executed in a number to a plus, the time complexity is O (F. N- );

If a thing has been counted out, then we'll survive it, like direct access later, no longer recursive, which is the memory of the search:

int f[233];
bool g[233];

int dfs(int n)
{
    if (n==0) return 0;
    if (n==1) return 1;
    if (g[n]) return f[n];
    f[n] = dfs(n-2) + dfs(n-1);
    g[n]=true;
    return f[n];
}

 

Dynamic programming has features:

Status: What To calculate;

Transfer equation: how to count;

No aftereffect: dynamic programming state among all the component directed acyclic graph;

Sometimes dynamic programming is not necessarily from 1 -> n, it may be out of order; but we should always remember that it is a DAG, so each state can be seen as a node, topological sorting, and then It has become the order of;

 

Common types of dynamic programming:

1. knapsack problem:

01 Backpack:

the n items, m capacity, the value of each item and having a volume, into the article does not exceed the capacity of the backpack, and seek to maximize the value;

The first dimension: f [i] means that we have now put away before the i-th item;

Second dimension: f [j] denotes the article go into and how much volume;

Then the state is: f [i] [j] have tried to represent us before i went into the two items are, for the volume and j can take the time to the maximum value;

How transfer?

If the i + 1-th item into the hold: f [i] [j] = f [i + 1] [j];

If the i + 1-th items put to: f [i + 1] [j + v [i + 1]] = f [i] [j] + w [i + 1];

This method is to update themselves to others.

We now updates itself with the others:

If the i-th item into the hold: f [i] [j] = f [i-1] [j];

If the i-th items put to: f [i] [j] = f [i-1] [jv [i-1]] + w [i];

Note operator side edge take max;

#include<iostream>

using namespace std;

int n,m,w[233],v[233];
int f[233][233];

int main()
{
    cin >> n >> m;
    for (int a=1;a<=n;a++)
        cin >> v[a] >> w[a];
    for (int i=1;i<=n;i++)
        for (int j=0;j<=m;j++)
        {
            f[i][j] = f[i-1][j];
            if (j >= v[i]) f[i][j] = max(f[i][j],f[i-1][j-v[i]]+w[i]);
        }
    int ans=0;
    for (int a=0;a<=m;a++)
        ans = max(ans,f[n][a]);
    cout << ans << endl;
    return 0;
}

 

 

Full backpack:

Consider each item with a maximum value can be unlimited.

State or unchanged.

Reconsider the state transition equation:

Because each item can put a number, so we look at the i-th enumerate how many items put;

#include<iostream>

using namespace std;

int n,m,w[233],v[233];
int f[233][233];

int main()
{
    cin >> n >> m;
    for (int a=1;a<=n;a++)
        cin >> v[a] >> w[a];
    for (int i=1;i<=n;i++)
        for (int j=0;j<=m;j++)
            for (int k=0;k*v[i]<=j;k++)     //注意上限 
                f[i][j] = max(f[i][j],f[i-1][j-k*v[i]]+k*w[i]);
    int ans=0;
    for (int a=0;a<=m;a++)
        ans = max(ans,f[n][a]);
    cout << ans << endl;
    return 0;
}

But the rise time complexity O (the n- 3 ), we have to think about optimization:

 

 

Limited backpack:

Consider each item with a maximum value can be limited times.

We enumerate each item directly with how many times:

 

We can be bundled with the original article:

In this case, we use the original 0 to 13 times of any knapsack problem became 01 once, it is to use these four tied with whether once this transformation.

Time complexity of O (n- 2 K), K is the article can be divided into several bundles;

How split bundle? Similar to binary:

If we can use an item 26:

We can split into 26: 1,2,4,8 ......, we are going to split 16, but only a 26-1-2-4-8 = 11, significantly less than 16, the last packet the size is 11;

 

We found that the number of split into a bundle of log n, then the time complexity is: O (nm log n);

We read when we should deal with what bundle.

 

2. Basic Dynamic Programming

Classic example: digital triangle

Status: f [i] [j] the largest number of come elapsed in row i and column j is the largest number;

Considering the f [i] [j] from the top or f [i-1] [j] came from the upper left or f [i-1] [j-1] came, so take a max like;

State transition equation: f [i] [j] = max (f [i-1] [j], f [i-1] [j-1]) + a [i] [j];

 

Because too easy, add a condition: find the final answer mod 100 maximum.

If we define the state as just as words are wrong, because if not necessarily large and modulus maximum, that is the best value in front of the optimal value can not be determined later;

The question one more condition, then we add a dimension;

Status is defined: f [i] [j] [k] we reached the position i-th row j-th column so that the mold 100 and the maximum value is equal to k possible feasible;

State transition equation:

From (i, j) to go down: f [i + 1] [j] [(k + a [i + 1] [j])% 100] = 1;

Right from the lower deck (i, j): f [i + 1] [j + 1] [(k + a [i + 1] [j + 1])% 100] = 1;

Initialization: f [1] [1] [a [1] [1]% 100] = 1;

 

Rise longest sequence

State is set: f [i] indicates the length of the longest sequence increase this number i when a last number of the most;

f [ i ] = max ( f [ j ] + 1 ),1 <= j <= i 且 aj < ai

J enumeration when we can use the tree line;

Acceleration data structure is a dynamic programming values ​​commonly used method;

 

3. Interval Dynamic Programming

Classic example: the merger stones

N-stack stones, stones can only merge adjacent piles, the cost of the cost and the weight of piles of stones, stones piled n will seek to minimize the cost of a combined heap of stones;

State is set: f [i] [j] denotes the i-th stack stones incorporated into the minimum cost of the j-th stack stones;

Initialization: f [i] [i] = 0, to merge into their own expense is 0;

State transition equation:

We will be able to find a dividing line, making the first boundary stones left all merged into a pile, all the stones to the right of the dividing line merge into a pile, and then finally merge two piles of stones;

So we can enumerate in a boundary k, the left side of the answer is f [i] [k], the right answer is f [k + 1] [j], then f [i] [j] = min (f [i ] [k] + f [k + 1] [j] + i ~ j and interval), and intervals and then the prefix can be maintained;

The final answer is f [1] [n] (the first stack to the n-stack merged gravel stones);

Before finishing details please see my blog (fog [portal]

We should first dimension to enumerate Length:

If we follow the left from point 1 ~ n enumerated as a first dimension, then if we require f [1] [n], we should use f [1] [i] + f [i + 1] [n] to update the answer, then, f [i + 1] [n] calculated a thing? Obviously not! Because we left endpoint from small to large, now only 1 to enumerate it, i certainly have not been updated, so it's wrong! So we enumerate interval length according to the first dimension is: the length of a section i of section i must be less than the length of two to update, so it.

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int read()
{
    char ch=getchar();
    int a=0,x=1;
    while(ch<'0'||ch>'9')
    {
        if(ch=='-') x=-x;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        a=(a<<3)+(a<<1)+(ch-'0');
        ch=getchar();
    }
    return a*x;
}
int n,a[201],fminx[201][201],fmaxn[201][201];
long long sum[201];
int main()
{
    n=read();
    for(int i=1;i<=n;i++) 
    {
        a[i]=read();
        a[n+i]=a[i];
    }
    for(int i=1;i<=n*2;i++) 
    {
        sum[i]=sum[i-1]+a[i];
        fminx[i][i]=0;
        fmaxn[i][i]=0;
    }
    for(int i=2;i<=n;i++)           //枚举区间长度 
    {
        for(int j=1;i+j<=2*n+1;j++)   //枚举区间左端点
        {
            int r=i+j-1;
            fmaxn[j][r]=0;
            fminx[j][r]=1e9;
            for(int k=j;k<r;k++)
            {
                fmaxn[j][r]=max(fmaxn[j][k]+fmaxn[k+1][r],fmaxn[j][r]);
                fminx[j][r]=min(fminx[j][k]+fminx[k+1][r],fminx[j][r]);
            }
            fmaxn[j][r]+=sum[r]-sum[j-1];
            fminx[j][r]+=sum[r]-sum[j-1];
        } 
    }
    int minx=1e9,maxn=-1e9;
    for(int i=1;i<=n;i++) 
    {
        minx=min(minx,fminx[i][i-1+n]);
        maxn=max(maxn,fmaxn[i][i-1+n]);
    }
    printf("%d\n%d",minx,maxn);
    return 0;
} 

 

Matrix Multiplication

N matrix calculation matrix multiplication, custom order of operations, asked a minimum of several operations?

After multiplying two matrices, it will generate a new matrix, the matrix is ​​consolidated.

States are defined: f [l] [r] l represents the first matrix is ​​multiplied to the r matrix how many times;

State transition equation: F [L] [R & lt] = min (F [L] [K] + F [K +. 1] [R & lt] + A L * A K +. 1 * A R & lt +. 1 ), L <= K <= r;

 

4. Status compression dynamic programming

See more examples:

Graphic design there are n points, the coordinates of each point is (X I , Y I  ), Q for all points from 01 points and finally completed the shortest path back One point.

First, each point there is no need to go twice, walked once is enough.

Variation:

At which point 1. Current;

2. point through which (we need never walked away a selected point inside);

State is set: f [s] [i] I have now come to the i-th point, through which the point (S);

But how come what point is represented by an integer?

We will use the state of compression: put an array compressed into a number.

If through a point, to give the corresponding binary 1; corresponding to did not come to have a binary 0;

Boundary conditions:

f [1] [0] = 0, I only go 0 points (only 1 bit 0, 1), the current position at 0, time is 0;

State transition equation:

We did not find a point to go through just fine.

J-bit enumerate a j, s look is not a binary 0, 0 if it is left j, j-bit and put into 1;

Note first enumeration state in the enumeration of each point, because we take the point that more and more;

 

Such problem is the Traveling Salesman Problem (TSP problem), the optimal time complexity is O (2 n- * n- 2 ), it can be shaped pressure data to be DP n <= 22, the range;

 

Guess you like

Origin www.cnblogs.com/xcg123/p/11200008.html