B - Lawrence HDU - 2829 does not write the slope dp dp transition equation

B - Lawrence

 HDU - 2829 

The topic I find hard, hard dp not write in this equation.

Read online solution to a problem, I read a long time to understand this transition equation dp

DP [i] [j] indicates that 1 ~ j j bits and end with a minimum weight into i sections and

Then define an array W [a, b] is the weight of a to b and, and note that this is not a prefix, but the kind and weight of the subject to

Is such a to b 4 5 1 2 Its Strategic Value is 4 * 5 + 4 * 1 + 4 * 2 + 5 * 1 + 5 * 2 + 1 * 2 = 49. 

w[a,b]=49

Then define a val [i] == w [1, i] means that the prefix weights and val [i] = val [i-1] + sum [i-1] * a [i]

Because this w [a, b] be introduced not directly, but can be pushed by means of the prefix.

求w[a+1,b]=val[b]-val[a]-(sum[b]-sum[a])*sum[a]

Then the equation dp can launch it

dp[i,j]=min(dp[i-1,k]+w[k+1,j])

But the direct violence n ^ 3 is definitely not over, it needs to be optimized, and this formula is not pushed through before the slope of the optimization equation like.

If dp [i-1, k] k addition there is also the value, generally can be optimized by the slope dp optimization.

And then it can be introduced as before formula (before referring to D - Pearls HDU - 1300 bipartite slope dp +   slope A DP - the Print Article This article was HDU - 3507 )

令 F[h]=dp[i-1][h]-val[h]+sum[h]*sum[h]

所以G[h,k]=(F[h]-F[k)/(sum[h]-sum[k])<sum[j]

Then the same is deduced

If there are i> j> k G [i, j]> G [j, k]

1 G [i, j]> Gj, k]> [t] k j excellent than sum, j preferred ratio i

2 G [i, j]> sum [t]> G [j, k] j is less than i then preferably, j k ratio preferably

3 sum [t]> G [i, j]> G [j, k] i than the ratio k j j excellent excellent

If i> j> k G [i, j] <G [j, k]

1 G [i, j] <G [j, k] <sum [t] j ratio of k i is smaller than j excellent excellent

2. G [i, j] <sum [t] <G [j, k] i than the ratio k j j excellent excellent

3 sum [t] <G [i, j] <G [j, k] j ratio i j k of excellent excellent

Under such circumstances, j is certainly to be excluded, so that if i is inserted from the rear when the front and j, if it constitutes less than the slope of the slope number and the number of the previous configuration,

Well, this is certainly not the j.

Because this sum is monotonic and the prefix, it is possible to optimize the queue monotone dp.

 

   

  

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <iostream>
#include <string>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
const int maxn = 1e5 + 10;
typedef long long ll;
ll dp[1100][1100], sum[1100], val[1100], a[1100];
int que[maxn];

ll up(int i,int j,int k)
{
    return dp[i - 1][j] - val[j] + sum[j] * sum[j] - (dp[i - 1][k] - val[k] + sum[k] * sum[k]);
}

ll down(int j,int k)
{
    return sum[j] - sum[k];
}

ll DP(int i,int j,int k)
{
    return dp[i - 1][k] + val[j] - val[k] - (sum[j] - sum[k])*sum[k];
}

int main()
{
    int n, m;
    while (scanf("%d%d", &n, &m) && (n + m)) {
        sum[0] = 0;
        val[0] = 0;
        for (int i = 1; i <= n; i++) {
            scanf("%lld", &a[i]);
            sum[i] = sum[i - 1] + a[i];
            val[i] = val[i - 1] + sum[i - . 1 ] * A [I]; 
        } 
        for ( int I = . 1 ; I <= n-; I ++) DP [ . 1 ] [I] = Val [I]; // note that this subject initialization 
        for ( int I = 2 ; i <= m + . 1 ; i ++ ) {
             int head = 0 , tail = 0 ; // Note dp [i, j] is defined based on j end into a minimum value of i blocks 
            que [tail ++] = i - . 1 ; // since the period to be divided into i blocks, the number of front least be accounted i-1, and may be followed by another into a whole, not missing note case 
            for ( int J = i; J <= n-; ++ j) { // Note that this j i must start from
                 while (head + 1 < tail&&up(i, que[head + 1], que[head]) <= sum[j] * down(que[head + 1], que[head])) head++;
                dp[i][j] = DP(i, j, que[head]);
                while (head + 1 < tail&&up(i, j, que[tail - 1])*down(que[tail - 1], que[tail - 2]) <= up(i, que[tail - 1], que[tail - 2])*down(j, que[tail - 1])) tail--;
                que[tail++] = j;
            }
        }
        printf("%lld\n", dp[m + 1][n]);
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/EchoZQN/p/11402172.html