Codeforces Round #278 (Div. 2) D. Strip

来源:互联网 发布:ajax获取前台数据 编辑:程序博客网 时间:2024/06/06 05:07

题意:

给你一些数字,求分段的最小数目,满足每一段至少 l 个数字,每一段极差不超过 s 

解题报告:

看到这题第一反应是单调队列,这个思路肯定可做(只是我觉得维护起来有些麻烦

第二想法是DP,长得就是一脸DP的样子(只是我作为DP弱渣,实在是对转移方程无能为力

第三想法就是下面这种想法,记录必不选区间(极差大于S),然后将必不选区间进行分割,用类似贪心的做法,记录分割区间位置最小的值,如果现在的需要分割的区间,长度到不了L,则必不行

必不选区间必须分成两个,则必不选区间的各个端点,分割在不同的区域,最小分割(必比不选区间个数+1)

//      whn6325689#include <algorithm>#include <iostream>#include <iomanip>#include <cstring>#include <climits>#include <complex>#include <fstream>#include <cassert>#include <cstdio>#include <bitset>#include <vector>#include <deque>#include <queue>#include <stack>#include <ctime>#include <set>#include <map>#include <cmath>using namespace std;typedef long long ll;typedef long double ld;typedef pair<ll, ll> pll;typedef complex<ld> point;typedef pair<int, int> pii;typedef pair<pii, int> piii;typedef vector<int> vi;#define CLR(x,y) memset(x,y,sizeof(x))#define mp(x,y) make_pair(x,y)#define pb(x) push_back(x)#define lowbit(x) (x&(-x))#define MID(x,y) (x+((y-x)>>1))#define eps 1e-9#define INF 0x3f3f3f3f#define LLINF 1LL<<62template<class T>inline bool read(T &n){    T x = 0, tmp = 1;    char c = getchar();    while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();    if(c == EOF) return false;    if(c == '-') c = getchar(), tmp = -1;    while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();    n = x*tmp;    return true;}template <class T>inline void write(T n){    if(n < 0)    {        putchar('-');        n = -n;    }    int len = 0,data[20];    while(n)    {        data[len++] = n%10;        n /= 10;    }    if(!len) data[len++] = 0;    while(len--) putchar(data[len]+48);}//-----------------------------------const int MAXN=100100;int a[MAXN];vi duan;int main(){    int n, s, l;    read(n), read(s), read(l);    for(int i = 1; i <= n; i ++)        read(a[i]);    int maxx = 1, minn = 1;    for(int i = 1; i <= n; i ++)    {        if(a[maxx] < a[i])            maxx = i;        else if(a[maxx] == a[i] && maxx <= minn)            maxx = i;        if(a[minn] > a[i])            minn = i;        else if(a[minn] == a[i] && minn <= maxx)            minn = i;        if(abs(a[maxx] - a[minn]) > s)        {            duan.push_back(min(maxx, minn));        //维护极差区间            duan.push_back(max(maxx, minn));            maxx = minn = max(maxx, minn);        }    }    int ans = duan.size() / 2 + 1;    int pre = 0;    for(int i = 0; i < duan.size(); i += 2)    {        int L = duan[i], R = duan[i + 1];        if(R - pre - 1 < l)            ans = -1;        pre = max(L, pre + l);    }    if(n < l || (n - pre) < l)        ans = -1;    printf("%d\n", ans);    return 0;}


0 0
原创粉丝点击