Codeforces Round #278 (Div. 1) B. Strip
来源:互联网 发布:订餐的软件 编辑:程序博客网 时间:2024/06/07 20:55
题目链接:http://codeforces.com/problemset/problem/487/B
题意是给一个数组,然后要求把这个数组分成几段,每一段最值差不超过S,每一段的区间长度不少于L,问最少能够分成多少段?
如果无解输出-1.
一开始观察一下发现每一段区间的最值差会随着长度的增加而增加,可以通过二分找到每个数字向左能延伸的最大范围,然后
定义dp[i]为到第i个数字能够划分的最少区间的个数。 dp[i]可以在这么一个区间内进行转移[l , r],l是上面所说的二分找到的每个数字向左延
伸的最左边位置,r是i-L+1,我们在这个区间里面找到一个j,使得dp[j-1]最小,代表第i个数字和第j个数字划分到同一段里,dp[i] = dp[j] + 1;
因此我们实际上要维护的就是[l-1 , r-1]这么一个区间的最小值,由于数据范围比较大我们用线段树树状数组之类的维护一下两个东西,
一个是dp的区间最值,一个是二分过程中任意一段区间的最值差即可。
#include<cmath>#include<algorithm>#include<cstring>#include<string>#include<set>#include<map>#include<time.h>#include<cstdio>#include<vector>#include<stack>#include<queue>#include<iostream>using namespace std;#define LONG long longconst int INF=0x3f3f3f3f;const LONG MOD=1e9+61;const double PI=acos(-1.0);#define clrI(x) memset(x,-1,sizeof(x))#define clr0(x) memset(x,0,sizeof x)#define clr1(x) memset(x,INF,sizeof x)#define clr2(x) memset(x,-INF,sizeof x)#define EPS 1e-10#define lson l , mid , rt<< 1#define rson mid + 1 ,r , (rt<<1)+1#define root 1, n , 1const int MAXN = 1e5+10;struct Tree{ LONG Max , Min ;};Tree tree[MAXN<<2] ;int n ;int dp[100010] ;int idx[100010] ;int lowbit(int x){ return x&(-x);}void Insert(int i , int val ){ idx[i] = val ; while(i <= n) { idx[i] = min(idx[i] , val) ; i+= lowbit(i) ; }}int query(int l ,int r ){ int ans =idx[r] ; while(1) { ans = min(ans , idx[r]) ; if(r == l)break ; r -- ; for( ; r - l >=lowbit(r); r-= lowbit(r)) ans = min(idx[r] , ans ); } return ans ;}void Push_up(int rt){ tree[rt].Max = max(tree[rt<<1].Max , tree[rt<<1|1].Max); tree[rt].Min = min(tree[rt<<1].Min , tree[rt<<1|1].Min) ;}void build_tree(int l , int r ,int rt){ if(l == r) { scanf("%lld",&tree[rt].Max); tree[rt].Min = tree[rt].Max ; return ; } int mid = (l + r) /2 ; build_tree(lson) ; build_tree(rson) ; Push_up(rt) ;}LONG Query1(int L , int R , int l , int r ,int rt){ if( L <= l && r <= R ) { return tree[rt].Max ; } int mid = ( l + r) / 2; LONG ans = -INF; if(L <= mid ) ans =max(ans, Query1( L ,R , lson )); if( R > mid) ans = max(ans , Query1( L , R , rson)) ; return ans ;}LONG Query2(int L ,int R ,int l, int r ,int rt){ if(L<= l && r <=R) { return tree[rt].Min ; } int mid = (l +r )/2 ; LONG ans = INF ; if(L <= mid) ans = min(ans , Query2(L ,R , lson )) ; if(R > mid) ans = min( ans , Query2( L , R , rson)) ; return ans ;}int check(int l , int r , LONG s){ LONG x = Query1(l , r ,root); LONG y = Query2(l , r , root ); if(x - y <= s) return 1; return 0 ;}void Init(){ clr1(dp); clr0(idx);}int main(){ int L; LONG s ; cin>> n >>s>> L; build_tree(1 , n , 1) ; Init() ; dp[1] = 0 ; for(int i = 1; i <= n; ++ i) { int l = 1,r = i - L + 2 ; int mid ; while(l< r) { mid = ( l + r) / 2 ; if(check( mid , i ,s)) r = mid; else l = mid + 1; } if(l >= i-L+2) { Insert(i + 1, dp[i + 1 ]) ; continue ; } int ll = max(l , p1); int rr = i - L + 1; dp[i + 1] = query(ll , rr) + 1; Insert( i + 1 , dp[i+1]); } if(dp[n+1] >= 1000000) cout<<-1<<endl; else cout<<dp[n+1]<<endl;}
1 0
- Codeforces Round #278 (Div. 1) B. Strip
- Codeforces Round #278 (Div. 1) B. Strip(Dp+multiset维护)
- Codeforces Round #278 (Div. 2) D. Strip
- Codeforces Round #278 (Div. 1) B
- Codeforces Round #278 (Div. 1) 解题报告 A.B.
- Codeforces Round #278 (Div. 2) A B
- Codeforces Round #278 (Div. 2) A, B
- Codeforces Round #278 (Div. 2) B
- Codeforces Round #131 (Div. 1) B. Numbers
- Codeforces Round #119 (Div. 1) B. AlgoRace
- Codeforces Round #215 (Div. 1) <A-B>
- Codeforces Round #225 (Div. 1) B. Volcanoes
- Codeforces Round #230 (Div. 1)B,C
- Codeforces Round #239 (Div. 1)(A,B)
- Codeforces Round #253 (Div. 1)-A,B
- Codeforces Round #254 (Div. 1)-A,B
- Codeforces Round #240 (Div. 1)B
- Codeforces Round #259 (Div. 1) B题
- Linux设备模型分析之kobject
- 如何利用Reactjs进行简单的表单验证
- 138. Copy List with Random Pointer
- UVA 10233 Dermuba Triangle
- java实现redis
- Codeforces Round #278 (Div. 1) B. Strip
- BZOJ P1041[HAOI2008]圆上的整点
- 设置Ubuntu系统的分辨率--解决vmware workstaion中shell窗口太小的问题
- C语言中运算符的总结
- POJ 1681 画家问题
- 项目实战篇-餐馆管理系统—MFC,PHP,MySql:6.订单管理模块
- leetcode 76. Minimum Window Substring
- xcrun: error: unable to find utility "instruments", not a developer tool or in PATH
- sizeof和strlen的一些用法和区别