D5 (md too long did not finish)

Dynamic Programming

Three common implementations

For a Fibonacci number, we would like to request the value of n items, one by one recursively need to ask
to see the code

    f[o] = 0;
    f[1] = 1;
    for (int i = 2; i <= n; ++i)
        f[i] = f[i-1] + f[i-2];
    cout << f[n] << endl;

This belongs with the other results to count their knot, if we change the way to write, became with their values updated value of others

    f[o] = 0;
    f[1] = 1;
    for (int i = 0;i <= n; ++i)
    {
        f[i + 1] += f[i];
        f[i + 2] += f[i];
    }

Both ways are there, but there are some problems have stuck out different wording of the cancer operation, so both must grasp

The final wording is

Memory search

int dfs (int n) {
    if (n == 0)
        return 0;
    if (n == 1)
        return 1;
    return dfs(n - 1) + dfs(n - 2);
}

The time complexity is O (F [n]), because we can only use 1,0 to slowly go together

Interestingly Fibonacci item n and 2 ^ n almost a level, slow death, and why? ?

You consider f [n-1] is forget twice, which caused great waste of time, so we can already consider seeking out value for recording, which is memory search
g [i] on behalf of the there is no number to be counted out

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];
}

If you have already been counted out before, direct return on the line, so they do not have a secondary computing

And finally into the dynamic programming friends

The state is saying what you want to count, the transfer equation is saying how you want to count, to understand no after-effect of the composition of a DAG between all states is dynamic programming

Na Feibo Fibonacci example

1. The state is f [n]

2. The transfer equation is f [n] = f [n-1] + f [n-2]

Of course, this is a no aftereffect of things

When we encounter some of the more abnormal the title transfer order it? DAG are considered among the state, we can run side topological sorting of the state, then you can for it again on the line

Some special types of DP

Mainly the following

Knapsack problem

The most easy questions

luogu 1616 crazy herbs

给定n种物品和一个背包。
物品i的体积是vi,其价值为wi,背包的容量为m。
应该如何选择装入背包中的物品,使得装入背包中物品的总价值最大?

How to design state? Considered to be a items place an item, so there is a change in what I now put before the i-th article, the second dimension is what I put in the items and how much volume

Therefore, the status of this problem should be F [i] [j] have tried represents the i-th item preamplifier (not guaranteed to have been placed), and the volume is consumed j

Transfer equation is to consider how to put the next item, it is clear that only put or hold, then the state transition equation is

从别人更新自己
f[i][j] = max(f[i - 1][j], f[i - 1][j - v[i] ] + w[i]);

code show as below

int n, m, w[233], v[233];
int f[233][12345678];
int main()
{
    cin >> n >> m;
    for (int i = 1; i <= n; ++i)
        cin >> w[i] >> v[i];
   for (int i = 1; i <= n; i++)
        for (int j = V; j >= w[i]; j--)
            f[j] = max(f[j], f[j - w[i]] + v[i]);
}

Items can put unlimited backpack (unlimited knapsack problem)

Enumerate what a few items to put on the line

    for (int i = 1; i <= n; ++i)
        for (int j = 0; j <= n; ++j)
            for (int k = 0; k * v[i] <= j; k++)
                f[i][j] = max(f[i][j], f[i][j - k * v[i]] + k * w[i]);

But you are using a triple loop, it will certainly be launched into t
we consider a problem, the same items take more, in fact, it is how many times repeated transferred to it, so we changed the code

    for (int i = 1; i <= n; i++)
        for (int j = w[i]; j <= V; j++)
            f[j] = max(f[j], f[j - w[i]] + v[i]);

Line, get away

Limited backpack

For a limited number of times, we can split it into several collections, the binary split manner, such as split 30
I can split into 1, 2, 4, 8, 15. It is worth noting that our final number is not necessarily in line with integer powers of two, in fact, it is the last of the poor

The Code

int n, m, w[233], v[233], cnt = 0;
int f[233][12345678];
int main()
{
    cin >> n >> m;
    for (int i = 1; i <= n; ++i)
    {
        cin >> w[i] >> v[i] >> z;
        while (x <= z)
        {
            v[++cnt] = v[i] * x;
            w[cnt] = w[i] * x;
            z -= x;
            x *= 2;
        }
        if (z > 0)
        {
            v[++cnt] = v[i] * z;
            w[cnt] = w[i] * z;
        }
    }
    for (int i = 1; i <= n; i++)
        for (int j = V; j >= w[i]; j--)
            f[j] = max(f[j], f[j - w[i]] + v[i]);
}

Backpack so finished

DP basis

Example a P1216 [IOI1994] [USACO1.5] Digital Number Triangles triangle

I will not face questions posted, you can certainly think of dp, or else he would not ah hhh this
in mind that for a point, he is coming from the upper left or upper right corner, so we can get the transfer equation

f[i][j] = max(f[i - 1][j], f[i - 1][j - 1]);

Line finished

Transformation title (EX NumberTriangles)

We want to make the right to find out the value after the value and% m is the largest.

At first my idea is to use a structure to keep weight after the actual weights and modulus, but is not enough, because they no longer meet the optimal substructure of principle. (That is to say between the actual size and weight modulo weights are not necessarily linked, so we can not use the state transition equations to find the maximum and minimum)

We consider adding a dimension to open a bool array f

f [i] [j] [
k] represents the j-th column is the path walked weight of the i-th row and% m = k Is it possible, then how do we transfer it

Or to consider only one point may be evaluated over from its top left and top right, then we can come to a state transition equation

f[i][j][k] = f[i - 1][j - 1][(k - a[i][j]) % m] || f[i - 1][j][(k - a[i][j]) % m]

Border situation, then, is

f[1][1][a[1][1] % m] = true(按照状态的定义来理解就行,很好理解)

Then we iterate over the end result can be a

for (int i = 1; i <= n; ++i)
    {
        for (int j = 1; j <= m; ++j)
        {
            if (f[n][i][j])
                ans = max(ans, j);
        }
    }

I wondered if the code does not matter on behalf of the chant, but anyway, I wrote that zhx white shameless whore what hhh

#include <bits/stdc++.h>
using namespace std;
const int Mod = 100;
const int maxn = 25 + 5;
int maps[maxn][maxn];
bool dp[maxn][maxn][100];
int main()
{
    int n;
    while (~scanf("%d", &n))
    {
        memset(maps, 0, sizeof(maps));
        memset(dp, 0, sizeof(dp));
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= i; j++)
                scanf("%d", &maps[i][j]);
        dp[0][0][0] = dp[0][1][0] = true; //这个初始化很重要
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= i; j++)
            {
                for (int k = 0; k <= 99; k++)
                {
                    int now;
                    if (dp[i - 1][j][k]) //当上一个这个数值存在时就可以加上当前状态的值
                    {
                        now = (maps[i][j] + k) % Mod;
                        dp[i][j][now] = true;
                    }
                    if (dp[i - 1][j - 1][k])
                    {
                        now = (maps[i][j] + k) % Mod;
                        dp[i][j][now] = true;
                    }
                }
            }
        int ans = 0;
        for (int i = 1; i <= n; i++)
            for (int k = 0; k <= 99; k++)
            {
                if (dp[n][i][k])
                {
                    ans = max(ans, k);
                }
            }
        printf("%d\n", ans);
    }
}

Some words

dp 10 minutes of God of extremely fast hardware, according to his own statements, dp for a title, can not solve the current dimension of time, it would add a dimension, the total run out

Rise longest sequence

DP [i] i is represented by the end of the longest sequence rise

Enumeration preceding word is transferred aj i is less than the number of Ai

for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= i; ++j)
            f[i] = max(f[i], f[j] + i);

Not difficult ah, time complexity of N ^ 2

But we have to strengthen data n <= 1e5, then how to do it

We certainly can not run again O (n ^ 2), ah, here consider tree line, is to use a learning segment tree yesterday seeking the best value for the interval method, the time complexity of direct reduced logn, this way, the total time complexity is nlogn

v = max (a1, a2, a3, ..... an), calculated each time f [i]

We built a tree line segment of length n, then directly be divided, that is the longest rising sequences at both ends of the range would certainly be his two sons and, so you figure it up a lot faster

DP range

Dp range of features that give you a bunch of things, you can only merge two adjacent things, general condition is
f [l] [r]
the minimum cost of the gravel pile r l represents the heap of stones to how much

Merge stones luogu1880

N stones piled there, Stone is ordered merge into a pile, defined as follows: 2 can only be moved adjacent stones piled merged, the number of a pile of stones takes newly synthesized. N find these stones piled merge into a pile total cost of the minimum (or maximum).

F. [L] [r]
denotes the l to r th stones piled heap of stones to be combined into one pair of the cost of stone

Do we find any problems when DP is take the old three steps (look for the state to find the boundary conditions, to find the state transition equation)

This boundary condition problem is when L = R, so F [l] [r] = 0 (l = r)

Then we look at the state transition equation, the last time we merge the two piles of stone must be merged into a pile of stones, and put a bunch of a bunch of left and right, due to the limitations of the topic, we can find that in any case the merger, the order of stone It is constant.

So we must find a dividing line, so that the left is the result of A1 ~ Ap, the right is Ap + 1 ~ Ar, then we only need to enumerate what position p on it. Therefore, the state transition equation is (all)

min(f[l][p] + F[p+1][r] + sum[l][r]);

Look at the code

int z[manx],f[maxn][maxn];

int main()
{
    cin>>n;
    for(int a=1;a<=n;a++)
        cin>>z[a];//表示石子数
    memset(f,0x3f,sizeof(f));//初始化为无穷大 
    
    for(int a=1;a<=n;a++)
        f[a][a]=0;
            
    //枚举左端点,右端点,断点 
    for(int l=1;i<=n;l++)//枚举左端点 
    {
        for(int r=l+1;r<=n;i++)//枚举右端点 
        {
            for(int p=l;p<r;p++)
            {
                f[l][r]=min(f[l][r],f[l][p]+f[p+1][r]+sum[l][p]);
                //左边合并的代价+右边合并的代价+这段区间的石子之和 
            }
        }
    }
    cout<<f[1][n]<<endl; 
    return 0; 
}

First of all the array assignment, then change it boundary conditions

We enumerate a left point, right enumerate a point, and then enumerate a breakpoint

Unfortunately, this is the wrong way to enumerate

Posted pictures
I obviously listened carefully for a long time ah feed

Because at any time, he does not meet the DP stage

You see, ah, you are calculating when to use f f [1] [n] [2] [n], but it has not been counted (what the hell)

So we have to enumerate interval length, and then modify the code on it

I do not know doing a title (melancholy

You n matrix, defined sequence, such that a minimum number of operations

And more like a question, probably means that the matrix are combined into a bunch of minimum cost

Transfer equation is

 s[j][i] = max(s[j][i], s[j][k] + s[k+1][i] + e[j] * e[k+1] * e[i+1]);

Shaped pressure DP

There are n points in the plane, requiring from 1 point to each point are gone again, for the shortest distance, the minimum spanning tree and have nothing, is a very simple two-dimensional plan, you can easily walk (large fog

First of all, we do not need to go twice the same point, then a point 01 that did not go through, we can easily use an n-bit binary number to store the shortest distance in its current state, so that the pressure-like

Transfer, then enumerate a j

Line Tou force on the line

Grass

To john on a pasture grass, turf no adjacent edges between each

State dp [i] [j] represents the i-th row before the grass seed over, s represents the i-th row of grass became what

k King

f [i] [j] [k] denotes the i-th row before the king species are finished, s represents the i-th row

Digital dp

Reads two positive integers L, R, L to R from asking how much the number, the answer is L-R + 1, which is certainly no challenge ah is not it, to challenge ourselves, we use what digital DP (large fog)

There is a thing called the prefix and conversion

Guess you like

Origin www.cnblogs.com/this-is-M/p/11222670.html