1. 程式人生 > >codeforces-487B Strip(dp+rmq+二分+水資料)

codeforces-487B Strip(dp+rmq+二分+水資料)

笑死,最壞情況下時間複雜度為O(n*nlogn)

思路:每次找前面最小l,使[l,i]滿足條件,dp[i] = dp[l-1]+1;


#include <stdio.h>
#include <string.h>
#include <ctime>
#include <stack>
#include <string>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <map>
#include <queue>
#include <vector>
using namespace std;
#define LL long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lowbit(x) (x&-x)

const int maxn = 1e5+7;
const int INF = 0x3f3f3f3f;

int rmq[maxn][20][2];
int mm[maxn],a[maxn];
int dp[maxn],n,s;

void initRMQ()
{
    mm[0] = -1;
    for(int i=1; i<=n; i++)
    {
        mm[i]=((i&(i-1))==0)?mm[i-1]+1:mm[i-1];
        rmq[i][0][0] = rmq[i][0][1] = a[i];
    }
    for(int j=1; j<=mm[n]; j++)
        for(int i=1; i+(1<<j)-1<=n; i++)
    {
        rmq[i][j][0] = max(rmq[i][j-1][0],rmq[i+(1<<(j-1))][j-1][0]);
        rmq[i][j][1] = min(rmq[i][j-1][1],rmq[i+(1<<(j-1))][j-1][1]);
    }
}

int qMin(int x,int y)
{
    int k = mm[y-x+1];
    return min(rmq[x][k][1],rmq[y-(1<<k)+1][k][1]);
}

int qMax(int x,int y)
{
    int k = mm[y-x+1];
    return max(rmq[x][k][0],rmq[y-(1<<k)+1][k][0]);
}

int f(int l,int r)
{
    return qMax(l,r)-qMin(l,r);
}

int findLeft(int l,int r,int i)
{
    int m,ret = -1;
    while(l<=r)
    {
        m = (l+r)>>1;
        if(f(m,i)<=s)
        {
            ret = m;
            r = m-1;
        }
        else
            l = m+1;
    }
    return ret;
}

int main()
{
    int l;
    while(scanf("%d%d%d",&n,&s,&l)!=EOF)
    {
        for(int i=1; i<=n; i++)
            scanf("%d",&a[i]);
        initRMQ();
        if(qMax(1,1+l-1)-qMin(1,1+l-1)>s)
        {
            //puts("this");
            puts("-1");
            continue;
        }
        for(int i=1; i<l; i++)
            dp[i] = maxn;
        dp[l] = 1;
        for(int i=l+1; i<=n; i++)
        {
            int t = findLeft(1,i-l+1,i);
            if(t!=-1)
            {
                while(dp[t-1]>=maxn&&t<=i-l)
                    t++;
                dp[i] = dp[t-1]+1;
            }
            else
                dp[i] = maxn;
        }

        if(dp[n]<maxn)
            printf("%d\n",dp[n]);
        else
            puts("-1");
    }
	return 0;
}


Strip time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output

Alexandra has a paper strip with n numbers on it. Let's call them a

i from left to right.

Now Alexandra wants to split it into some pieces (possibly 1). For each piece of strip, it must satisfy:

  • Each piece should contain at least l numbers.
  • The difference between the maximal and the minimal number on the piece should be at most s
    .

Please help Alexandra to find the minimal number of pieces meeting the condition above.

Input

The first line contains three space-separated integers n, s, l (1 ≤ n ≤ 105, 0 ≤ s ≤ 109, 1 ≤ l ≤ 105).

The second line contains n integers ai separated by spaces ( - 109 ≤ ai ≤ 109).

Output

Output the minimal number of strip pieces.

If there are no ways to split the strip, output -1.

Examples input
7 2 2
1 3 1 2 4 1 2
output
3
input
7 2 2
1 100 1 100 1 100 1
output
-1