D. 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 ai 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.

Sample test(s)
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
Note

For the first sample, we can split the strip into 3 pieces: [1, 3, 1], [2, 4], [1, 2].

For the second sample, we can't let 1 and 100 be on the same piece, so no solution exists.

题意是给出一个长度为n的序列,问最少能够分割多少分。

使得,每一分的长度大于等于l,最大值与最少值的差值最大为s 。

我的方法是3颗线段树,2颗维护最大最小值, 1棵维护 dp[i-1]+1 最小的位置。

然后二分出尽量左的位置使得最大最小值差值最大不超过s ,

然后从这个位置到当前位置取出 dp[i-1]+1 最小的位置。然后再更新。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <algorithm>
using namespace std; typedef long long LL;
const int N = ;
const int inf = 1e9+;
const double PI = acos(-1.0);
const double eps = 1e- ; #define root 1,n,1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define lr rt<<1
#define rr rt<<1|1 int n , m , dif , e[N] , dp[N];
int d_M[N<<] , d_m[N<<] , p_m[N<<]; void Up( int rt ) {
d_M[rt] = max( d_M[lr] , d_M[rr] );
d_m[rt] = min( d_m[lr] , d_m[rr] );
}
void Up2( int rt ) {
if( dp[ p_m[lr] - ] + < dp[ p_m[rr] - ] + ) p_m[rt] = p_m[lr] ;
else p_m[rt] = p_m[rr] ;
} void build( int l , int r , int rt ){
if( l == r ) {
p_m[rt] = l ; d_M[rt] = d_m[rt] = e[l] ; return ;
}
int mid = (l+r)>>;
build(lson) , build(rson) ;
Up(rt); Up2(rt);
} int temp_M , temp_m , temp_dpm; void update( int l , int r , int rt , int x , int val ) { if( l == r ) {
dp[ x ] = val ; return ;
}
int mid = (l+r)>> ;
if( x <= mid ) update( lson , x , val );
else update(rson,x,val);
Up2(rt);
} int get_min_pos( int l , int r , int rt , int L , int R ){
if( l == L && r == R ) {
return p_m[rt];
}
int mid = (l+r) >> ;
if( R <= mid ) return get_min_pos( lson , L ,R ) ;
else if( L > mid ) return get_min_pos( rson ,L ,R ) ;
else {
int temp_l = get_min_pos( lson , L , mid ) , temp_r = get_min_pos( rson , mid+ , R );
if( dp[ temp_l - ] + < dp[ temp_r - ] + ) return temp_l;
else return temp_r;
}
} void query( int l , int r , int rt , int L , int R ) {
if( l == L && r == R ) {
temp_M = max( temp_M , d_M[rt] ) ;
temp_m = min( temp_m , d_m[rt] );
return ;
}
int mid = ( l+r ) >>;
if( R <= mid ) query(lson,L,R);
else if( L > mid )query(rson,L,R);
else query(lson,L,mid) , query(rson,mid+,R);
} void init() {
for( int i = ; i <= n ; ++i ) dp[i] = inf ;
}
void clr() { temp_m = inf , temp_M = -inf; temp_dpm = inf ; } int find( int l , int r ){ int pos = - , goal = r ;
while( l <= r ) {
int mid = (l+r)>>;
clr(),query(root,mid,goal);
if( abs( temp_M - temp_m ) <= dif )
pos = mid , r = mid - ;
else
l = mid + ;
}
return pos;
}
void test() {
for( int i = ; i <= n ; ++i ) cout << dp[i] << ' ' ;cout << endl ;
}
void run () {
for( int i = ; i <= n ; ++i ) cin >> e[i] ;
init(),build(root);
for( int i = ; i <= n ; ++i ) {
int pos = find( , i ) ;
if( pos == - || i - pos + < m ) continue ;
if( pos - == i - m ) {
update( root , i , dp[ pos - ] + ) ;
continue ;
}
pos = get_min_pos( root , pos , i - m );
update( root , i , dp[ pos - ] + ) ;
}
if( dp[n] < inf )cout << dp[n] << endl ;
else cout << "-1" << endl ;
} int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
#endif // LOCAL
ios::sync_with_stdio(false);
while( cin >> n >> dif >> m )run() ;
}

之前一直不会set...

在cf上看别人的代码,被完爆码量。

begin() 返回指向第一个元素的迭代器
clear() 清除所有元素
count() 返回某个值元素的个数
empty() 如果集合为空,返回true(真)
end() 返回指向最后一个元素之后的迭代器,不是最后一个元素
equal_range() 返回集合中与给定值相等的上下限的两个迭代器
erase() 删除集合中的元素
find() 返回一个指向被查找到元素的迭代器
get_allocator() 返回集合的分配器
insert() 在集合中插入元素
lower_bound() 返回指向大于(或等于)某值的第一个元素的迭代器
key_comp() 返回一个用于元素间值比较的函数
max_size() 返回集合能容纳的元素的最大限值
rbegin() 返回指向集合中最后一个元素的反向迭代器
rend() 返回指向集合中第一个元素的反向迭代器
size() 集合中元素的数目
swap() 交换两个集合变量
upper_bound() 返回大于某个值元素的迭代器
value_comp() 返回一个用于比较元素间的值的函数
 
 
用两个set。
一个维护区间范围。
一个维护dp[i-1]+1最小。
set的好处是可以按照给出值查找并删除那个元素。
就相当于有两棵现成的红黑树,替代了线段树的功能了。
 
#include <bits/stdc++.h>
#define X first
#define Y second
#define INF 1000000009
using namespace std; typedef pair<int,int> pii; int n, s, l, a[];
int dp[];
set <pii> S, R; int main(){ scanf("%d %d %d", &n, &s, &l);
for(int i = ; i <= n; i ++)
scanf("%d", &a[i]); memset(dp, , sizeof dp); int j = ;
for(int i = ; i <= n; i ++){
S.insert(pii(a[i], i));
while(!S.empty() && S.rbegin()->X - S.begin()->X > s){
S.erase(pii(a[j], j));
j ++;
}
if(i >= l && dp[i - l] != -)
R.insert(pii(dp[i - l], i - l));
while(!R.empty() && R.begin()->Y < j - )
R.erase(R.begin());
if(R.empty())
dp[i] = -;
else
dp[i] = R.begin()->X + ;
} printf("%d\n", dp[n]); return ;
}

Codeforces 488D Strip (set+DP)的更多相关文章

  1. Codeforces #55D-Beautiful numbers (数位dp)

    D. Beautiful numbers time limit per test 4 seconds memory limit per test 256 megabytes input standar ...

  2. Codeforces 607B Zuma(区间DP)

    题目大概说,有n个颜色的宝石,可以消除是回文串的连续颜色序列,问最少要几下才能全部消除. 自然想到dp[i][j]表示序列i...j全部消除的最少操作数 有几种消除的方式都能通过枚举k(i<=k ...

  3. Educational Codeforces Round 63-D(基础DP)

    题目链接:https://codeforces.com/contest/1155/problem/D 题意:给定n个数,可以选择一段连续子段将其乘x,也可以不操作,求最大连续子段和. 思路:比赛时觉得 ...

  4. 2018.12.29 codeforces 940E. Cashback(线性dp)

    传送门 题意:给出一个nnn个数的序列,要求将序列分成若干段,对于一段长度为kkk的自动删去最小的⌊kc⌋\left \lfloor \frac{k}{c} \right \rfloor⌊ck​⌋个数 ...

  5. codeforces#1183H. Subsequences(字符串dp)

    题目链接: http://codeforces.com/contest/1183/problem/H 题意: 给出一个长度为$n$的字符串,得到$k$个子串,子串$s$的花费是$n-|s|$ 计算最小 ...

  6. Codeforces 864E Fire(背包DP)

    背包DP,决策的时候记一下 jc[i][j]=1 表示第i个物品容量为j的时候要选,输出方案的时候倒推就好了 #include<iostream> #include<cstdlib& ...

  7. CodeForces 77C Beavermuncher-0xFF (树形dp)

    不错的树形dp.一个结点能走多次,树形的最大特点是到达后继的路径是唯一的,那个如果一个结点无法往子结点走,那么子结点就不用考虑了. 有的结点不能走完它的子结点,而有的可能走完他的子节点以后还会剩下一些 ...

  8. ACdreamOJ 1154 Lowbit Sum (数字dp)

    ACdreamOJ 1154 Lowbit Sum (数位dp) ACM 题目地址:pid=1154" target="_blank" style="color ...

  9. 「SDOI2016」储能表(数位dp)

    「SDOI2016」储能表(数位dp) 神仙数位 \(dp\) 系列 可能我做题做得少 \(QAQ\) \(f[i][0/1][0/1][0/1]\) 表示第 \(i\) 位 \(n\) 是否到达上界 ...

随机推荐

  1. 安装weblogic中间件_test

    小编对他还不是很了解,等了解的时候小编吧这句话删除(注意) 如果过程中有问题的话请联系 QQ:291562721 weblogic是ORACLE商家,他是一门中间件服务: 因为一些安全的原因,扫描发现 ...

  2. AJAX - 实现一个简单的登录验证

    /**Ajax 编写流程 * 1.创建 XHR (XMLHttpRequest)对象 var xmlHttpReq = false; // var xmlHttpReq = ""; ...

  3. 前端学习(三十八)vue(笔记)

    Angular+Vue+React    Vue性能最好,Vue最轻=======================================================Angular     ...

  4. java Arrays工具类的操作

    package java08; /* java.util.Arrays是一个与数组相关的工具类,里面提供了大量的静态方法,用来实现数组常见的操作 public static String toStri ...

  5. 机器学习:1.K近邻算法

    1.简单案例:预测男女,根据身高,体重,鞋码 import numpy as np import matplotlib import sklearn from skleran.neighbors im ...

  6. 07.整合jsp、整合freemarker、整合thymeleaf

    整合jsp pom.xml部分内容 <packaging>war</packaging> </dependencies> <dependency> &l ...

  7. CentOS7.5 安装部署Apache+Mysql+Php

    系统:CentOS7.5 安装Apache 安装 yum -y install httpd 开启apache服务 systemctl start httpd.service 设置apache服务开机启 ...

  8. hdu 5964:平行四边形 【计算几何】

    打重现赛时,一点思路也没有,然后又看到这题AC数那么少,就直接放弃了.今天重新看了看,借鉴了下别人的,发现此题应该算是一道可解题. 看上去,这题的ans是同时有两个点作为自变量的函数(然而n^2复杂度 ...

  9. uwsgi部署django项目

    一.更新系统软件包 yum update -y 二.安装软件管理包及依赖 yum -y groupinstall "Development tools" yum install o ...

  10. mobx学习笔记04——mobx常用api

    1 可观察的数据(observable) observable是一种让数据的变化可以被观察的方法. 那些数据可被观察? -原始类型 String.Number.Boolean.Symbol -对象 - ...