Summer D9 T2 extra (monotone stack optimization DP)

The meaning of problems

A path had been divided into n segments, each segment has a height, a person has stride k, on his behalf up from one step to the first paragraphs x + k x, when h [x]> h [x + k] when consumed at least, not physical exertion, or consume little energy, seeking last section of road to the n-th physical, initially in the first paragraph the road.

For 30% of the data, to ensure that T = 1;
for the other 20% of the data, to ensure that N <= 500;
to 100% of the data, to ensure that n <= 1e6, T <= 10, ai in the int, 0 <K < n.

answer

Readily occur to transition equation f [i] = h [i] <h [j] f [j]:? F [j] +1 (ik≤j <i)

How to optimize it for different heights of the road, the equation is different, how to think about.

If the same thing equation, that is, within a range of length k f find the smallest, is not that monotonous stack it?

But different transfer equation, consider monotonous stack to stack the first and only pop up if he belongs to the range of relevant, as long as he can cover this range, he is the best, so it has nothing to do with removing the solution is not optimal. We do not remove the optimal solution is carried out in the tail, and the tail each comparison with the current value of the element you want to insert a.

So think about when the end of a certain team value than the value of superior current element: f when both values ​​are the same, if the tail shorter is certainly not good, because at the same value, he is more likely to bring the price of 1;

Then the tail element f f larger than the current element of it, the tail is not optimal, or that can be replaced, because even if the current element shorter, it brings the price of 1, the answer is to get the tail ≤ s answer;

f the tail of smaller elements will not play out, and the same as above, even if the higher current element, the tail element of the answer is also an answer ≤ current element.

#include<bits/stdc++.h>
using namespace std;

const int maxn=1000005;
int n,m,a[maxn];
int q[maxn],h,t;
int f[maxn];

void nice(){
    int k;scanf("%d",&k);
    h=1;t=0;
    q[++t]=1;
    f[1]=0;
    for(int i=2;i<=n;i++){
        while(h<=t&&i-q[h]>k) h++;
        f[i]= a[i]>=a[q[h]] ? f[q[h]]+1 : f[q[h]];
        while(h<=t&&((a[i]>a[q[t]]&&f[i]==f[q[t]])||(f[i]<f[q[t]]))) t--;
        q[++t]=i;
    }
    printf("%d\n",f[n]);
}

int main(){
    freopen("extra.in","r",stdin);
    freopen("extra.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    scanf("%d",&m);
    while(m--) nice();
}
/*9
4 6 3 6 3 7 2 6 5
2
2
5*/
View Code

 

Guess you like

Origin www.cnblogs.com/sto324/p/11222433.html