HDU 3916 Sequence Decomposition 【贪心】

这道题目的题意就是使用题目中所给的Gate 函数,模拟出输入的结果

当然我们分析的时候可以倒着来,就是拿输入去减

每次Gate 函数都会有一个有效范围

这道题目求的就是,找出一种模拟方法,使得最小的有效范围最大化。

是一道【贪心】题

参考了https://github.com/boleynsu/acmicpc-codes 的做法

b 数组中存放是 Sequence 的下标

这是一个O(n)的算法



if (a[i-1]<a[i]){

    int k=a[i]-a[i-1];

    while (k--) b[++bt]=i;

}

就是把 i 加进 b 数组,加 a[i] - a[i - 1]次

比如 a[i - 1] 为3 a[i] 为 5

那么在 b[ ] 中就会加两次 3 



else if (a[i-1]>a[i]){

    int k=a[i-1]-a[i];

    while (k--){

    ++bh;

    }

    answer = min(answer,i - b[bh - 1]);

}

bh 指针右移 k 次, 由于b 数组为非递减数组,故最后一位一定是最大的

取i - b[bh - 1] 与 answer比较,这个意思就是比较 Gate 函数的有效范围

如果有更小的范围,那么更新一遍

这里的 i 就是当前的位置, b[bh - 1]的意思……

  

 

//#pragma comment(linker, "/STACK:16777216") //for c++ Compiler

#include <stdio.h>

#include <iostream>

#include <cstring>

#include <cmath>

#include <stack>

#include <queue>

#include <vector>

#include <algorithm>

#define ll long long

#define Max(a,b) (((a) > (b)) ? (a) : (b))

#define Min(a,b) (((a) < (b)) ? (a) : (b))

#define Abs(x) (((x) > 0) ? (x) : (-(x)))

using namespace std;



const int MAXN = 2000000;



int N;

int a[MAXN];

int b[MAXN];

int bh,bt;



int main(){

    int T;

    scanf("%d",&T);

    while (T--){

        scanf("%d",&N);

        for (int i=1;i<=N;i++)

            scanf("%d",a+i);

        bh=0,bt=-1;

        int answer=N;

        a[0]=a[N+1]=0;

        for (int i=1;i<=N+1;i++){

            if (a[i-1]<a[i]){

                int k=a[i]-a[i-1];

                while (k--) b[++bt]=i;

            }

            else if (a[i-1]>a[i]){

                int k=a[i-1]-a[i];

                while (k--){

                    ++bh;

                }

                answer = min(answer,i - b[bh - 1]);

            }

        }

        printf("%d\n",answer);

    }

}

 当然在这里,也有一种更简单的方法也能过,不知道是不是算是数据水呢

#include<stdio.h>

int main(){

    int t, n, i, j, k, cnt;

    int a[10010], ans;

    scanf("%d",&t);

    while(t--){

        scanf("%d",&n);

        for(i = 1; i <= n; ++i){

            scanf("%d",&a[i]);

        }

        i = 1;

        ans = 0x3f3f3f3f;

        while(i <= n){

            j = i;

            while(a[j+1] >= a[j]){

                --a[j];

                ++j;

            }

            --a[j];

            cnt = j - i + 1;

            if(cnt < ans)

                ans = cnt;

            while(a[i] == 0)

                ++i;

        }

        printf("%d\n",ans);

    }

    return 0;

}

 

你可能感兴趣的:(sequence)