Easy Climb UVA - 12170 scroll dp + + monotonous discrete optimization queue

E.Easy Climb

Somewhere in the neighborhood we have a very nice mountain that gives a splendid view over the surrounding area. There is one problem though: climbing this mountain is very difficult, because of rather large height differences. To make more people able to climb the mountain and enjoy the view, we would like to make the climb easier.

To do so, we will model the mountain as follows: the mountain consists of n adjacent stacks of stones, and each of the stacks is hi high. The successive height differences are therefore hi+1-hi (for 1 ≤ i ≤ n-1). We would like all absolute values of these height differences to be smaller than or equal to some number d.

We can do this by increasing or decreasing the height of some of the stacks. The first stack (the starting point) and the last stack (the ending point) should remain at the same height as they are initially. Since adding and removing stones requires a lot of effort, we would like to minimize the total number of added stones plus the total number of removed stones. What is this minimum number?

Input

On the first line one positive number: the number of testcases, at most 100. After that per testcase:
One line with two integers n (2 ≤ n ≤ 100) and d (0 ≤ d ≤ 109): the number of stacks of stones and the maximum allowed height difference.
One line with n integers hi (0 ≤ hi ≤ 109): the heights of the stacks.
Output

Per testcase:
One line with the minimum number of stones that have to be added or removed or “impossible” if it is impossible to achieve the goal.
Sample Input

3
10 2
4 5 10 6 6 9 4 7 9 8
3 1
6 4 0
4 2
3 0 6 3
Sample Output

6
impossible
4

The 2008 ACM Northwestern European Programming Contest

The meaning of problems: highly n given stack, stack height requirements change, end to end can not be changed, so that the difference between any two adjacent queue number of <= d, find the minimum cost

 

answer:

First, if the data is small, then the range may be defined directly dp [i] [j] denotes the i-th processed before final height is a height b [j] of the minimum cost . Such a state is defined correctness is obvious.


But here is the range of d 10 ^ 9 Obviously we do not allow such violence to enumerate each state.
So it is necessary to prune. Observed a maximum height of only 100, but distribution in the range of 1e9's
certainly a lot of state will not be used, one should think of using discrete narrow.

 

First, consider only the case of three values: h1, h2, h3. Then the meaning of the questions, h2 of the range should be in the interval [h1-d, h1 + d], and [h3-d, h3 + d] intersection, i.e. h1 should [max (h1, h3) -d, min (h1 ] between, h3) + d. If this interval is an empty set, i.e. abs (h3-h1)> (3-1) * d, then naturally no solution, or:

1, if it is within the range h2, then no modification;

2, if h2 <max (h1, h3) -d, then modify the intersection of the lower bound of the interval max (h1, h3) -d;

3, if h2> min (h1, h3) + d, then the intersection modified upper bound min interval (h1, h3) + d.

It can be found at this simple question, h2 optimal modification only three cases. And we also found out that if you want to modify, highly modified must be in the form of hp + k * d. --- discrete narrow range

After discrete narrow the scope of it,



The following need to think about is the state transition equation.

dp[i][j]=min(dp[i-1][k])+abs(x[j]-h[i]);// j-d<=k<=j+d;

 

Monotone general queue has a head and tail pointers to maintain monotonicity two, where only a common writing head pointer to complete monotone queue, this problem directly in the B [] array to use when the queue monotonically
first

Specifically:

1. First, the left edge of the window maintenance, do not let the index k exceeds the window, if bk] <b [j] - d k ++ then (since b is from small to large arrays have been sorted), and without departing from the right border b [j] + d premise, if dp [i] [k + 1] <= dp [i] [k], then k ++;

Why it is the right of? And like said before the priority queue is not the same ah! In fact, the same operation, maintenance carefully recall how the priority queue operations: two pointers front, rear left boundary of the first update to prevent the current position beyond the range of the border, once beyond it front ++; then every time a new value to add to the mix to look at the size of the current element with the new value of the rightmost queue, if the new value is greater than the then rear--, the unwanted elements out of your queue until less than the new value, new value will be added, however, that in fact the top with a method pointer is exactly the same, but this step will delete unwanted value placed upon minimization, that is, when updating k .

         

#include <the iostream> 
#include <algorithm> 
#include <math.h>
 #define LL Long Long
 #define MX 999999999999
 the using  namespace STD; 
LL A [ 205 ], B [ 1000005 ], DP [ 205 ] [ 1000005 ]; / / DP [i] [J] represents the height of a mountain after the last i mountain to be completed before b [j] of minimum cost; 
int main () 
{ 
    int T; 
    CIN >> T;
     the while (T-- ) 
    { 
        int n-, D; 
        CIN >> >> n- D;
         for ( int= I 0 ; I <n-; I ++ ) 
            CIN >> A [I];
         IF (ABS (A [N- . 1 ] -a [ 0 ])> (N- . 1 ) * D) 
        { 
            COUT << " Impossible " << endl;
             Continue ; 
        } 
        LL CNT = 0 ;
         for ( int I = 0 ; I <n-; I ++) // discrete process will change the value of the mountain all the possible presence of the array b 
        {
             for ( int J = 0;j<n;j++)
            {
                b[cnt++]=a[i]+j*d;
                b[cnt++]=a[i]-j*d;
            }
        }
        int m;
        sort(b,b+cnt);
        m=unique(b,b+cnt)-b;
        for(int i=0;i<m;i++)//初始化dp
        {
            dp[0][i]=mx;
            if(b[i]==a[0])
                dp[0][i]=0;
        }
        for ( int I = . 1 ; I <n-; I ++ ) 
        { 
            int K = 0 ; // monotone queue head pointer 
            for ( int J = 0 ; J <m; J ++) // if the height of peaks to be changed to b [k ], then b [k] in the range [b [j] -d, b [j] + d], and to achieve optimum, or changed to b [k] -d, or change of b [k] + D 
            {
                 the while (K <m && B [K] <B [J] -d) // changed to the low value interval b [j] -d; find b [k]> = b [ j] -d exit 
                    K ++ ;
                 the while (K + . 1 <m && B [K + . 1 ] <= B [J] && + D DP [I- . 1 ] [K + . 1 ] <DP = [I- . 1 ] [K])//改变为区间上界值b[j]+d
                    k++;
                if(dp[i-1][k]==mx)
                    dp[i][j]=mx;
                else
                    dp[i][j]=dp[i-1][k]+abs(b[j]-a[i]);
            }
        }
        for(int i=0;i<m;i++)
        {
            if(b[i]==a[n-1])
                cout<<dp[n-1][i]<<endl;
        }
    }
}

 


         

Guess you like

Origin www.cnblogs.com/-citywall123/p/11260031.html