Codeforces 488D Strip (set+DP)
1 second
256 megabytes
standard input
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.
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 the minimal number of strip pieces.
If there are no ways to split the strip, output -1.
7 2 2
1 3 1 2 4 1 2
3
7 2 2
1 100 1 100 1 100 1
-1
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上看别人的代码,被完爆码量。
#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)的更多相关文章
- Codeforces #55D-Beautiful numbers (数位dp)
D. Beautiful numbers time limit per test 4 seconds memory limit per test 256 megabytes input standar ...
- Codeforces 607B Zuma(区间DP)
题目大概说,有n个颜色的宝石,可以消除是回文串的连续颜色序列,问最少要几下才能全部消除. 自然想到dp[i][j]表示序列i...j全部消除的最少操作数 有几种消除的方式都能通过枚举k(i<=k ...
- Educational Codeforces Round 63-D(基础DP)
题目链接:https://codeforces.com/contest/1155/problem/D 题意:给定n个数,可以选择一段连续子段将其乘x,也可以不操作,求最大连续子段和. 思路:比赛时觉得 ...
- 2018.12.29 codeforces 940E. Cashback(线性dp)
传送门 题意:给出一个nnn个数的序列,要求将序列分成若干段,对于一段长度为kkk的自动删去最小的⌊kc⌋\left \lfloor \frac{k}{c} \right \rfloor⌊ck⌋个数 ...
- codeforces#1183H. Subsequences(字符串dp)
题目链接: http://codeforces.com/contest/1183/problem/H 题意: 给出一个长度为$n$的字符串,得到$k$个子串,子串$s$的花费是$n-|s|$ 计算最小 ...
- Codeforces 864E Fire(背包DP)
背包DP,决策的时候记一下 jc[i][j]=1 表示第i个物品容量为j的时候要选,输出方案的时候倒推就好了 #include<iostream> #include<cstdlib& ...
- CodeForces 77C Beavermuncher-0xFF (树形dp)
不错的树形dp.一个结点能走多次,树形的最大特点是到达后继的路径是唯一的,那个如果一个结点无法往子结点走,那么子结点就不用考虑了. 有的结点不能走完它的子结点,而有的可能走完他的子节点以后还会剩下一些 ...
- ACdreamOJ 1154 Lowbit Sum (数字dp)
ACdreamOJ 1154 Lowbit Sum (数位dp) ACM 题目地址:pid=1154" target="_blank" style="color ...
- 「SDOI2016」储能表(数位dp)
「SDOI2016」储能表(数位dp) 神仙数位 \(dp\) 系列 可能我做题做得少 \(QAQ\) \(f[i][0/1][0/1][0/1]\) 表示第 \(i\) 位 \(n\) 是否到达上界 ...
随机推荐
- 数据结构 java概况
数据结构可以分为三种结构: 线性结构: 数组:栈:队列:链表:哈希表 树结构: 二叉树,二分搜索树,AVL,红黑树,Treap,Splay,堆,Trie,线段树,K-D树,并查集,哈夫曼树 图结构 邻 ...
- centos7系统之telnet命令rpm包安装
centos7系统之telnet命令rpm包安装 1. 下载安装包 rpm包下载位置:http://vault.centos.org/6.3/os/x86_64/Packages/ [root@ywb ...
- 如何去除inline-block的默认间距
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title&g ...
- java 计算时间差
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { Date d1 = df.parse(&quo ...
- 4G手机网络通信是如何被黑客远程劫持的?
你的4G手机网络通信是如何被黑客远程劫持的?如果您的移动运营商提供LTE(也称为4G网络),则需要小心,因为您的网络通信可能会被远程劫持. 中国一组研究人员发现了无处不在的LTE移动设备标准中的一些关 ...
- autoit3 脚本自动安装实例
软件自动安装的相关实例!贴出来用于参考,并部分相关语法与示例 #RequireAdmin If DriveMapGet("T:")=="" Then Drive ...
- ConcurrentLinkedQueue和LinkedBlockingQueue区别
原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11394436.html 线程安全队列类图 两者的区别在于 ConcurrentLinkedQueue基 ...
- python爬取“美团美食”汕头地区的所有店铺信息
一.目的 获取美团美食每个店铺所有的评论信息,并保存到数据库和本地 二.实现步骤 获取所有店铺的poiId 首先观察详情页的url,后面是跟着一串数字的,而这一串数字代表着每个店铺特有的id号,我们称 ...
- js-放大镜效果
jd或者淘宝的具体商品有个放大镜的效果.虽然网上类似插件琳琅满目,应用到项目上有诸多不便,自己抽点时间自己写了个类似插件,积累下代码,何乐而不为呢!!let‘go: 打算把此特效封装成个插件,先把最基 ...
- BLUEHOST香港主机FTP连接不上解决办法
昨天购买了BLUEHOST的香港主机后,以为一切顺风顺水,结果FTP却连接不上,用了多种FTP工具都不行,按官方博客要求开启了TSL仍然不行.经过一晚上的测试后终于成功,现分享出来. 方法一 ...