Codeforces 487B. Strip DP+线段树+二分
来源:互联网 发布:mac系统游戏 编辑:程序博客网 时间:2024/06/05 07:33
dp[ i ]表示到第i个位置最少要分多少下, dp[ i ] = min ( dp [ i ] , dp [ j ] + 1 ) j 在合适的范围内 ( 满足长度和最值差 )
对整个数组建立线段树维护最大值和最小值这样就可在nlogn的时间里求出某一段的最值差,这个范围是满足单调性的,所以对于每个i可以二分出j的最小值 .
对每个dp[i]建立线段树,可以在nlogn时间内求出最小的j.
所以总时间复杂度n^2logn
/* ***********************************************Author :CKbossCreated Time :2015年03月11日 星期三 23时20分17秒File Name :CF487B.cpp************************************************ */#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <string>#include <cmath>#include <cstdlib>#include <vector>#include <queue>#include <set>#include <map>using namespace std;const int maxn = 100100;const int INF = 1e6;int n,l,s;int a[maxn];int maxnum[maxn<<2],minnum[maxn<<2];/// seg tree#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1typedef pair<int,int> pII;void push_up(int rt){maxnum[rt]=max(maxnum[rt<<1],maxnum[rt<<1|1]);minnum[rt]=min(minnum[rt<<1],minnum[rt<<1|1]);}void build(int l,int r,int rt){if(l==r){minnum[rt]=maxnum[rt]=a[l];return ;}int m=(l+r)/2;build(lson); build(rson);push_up(rt);}pII query(int L,int R,int l,int r,int rt){if(L<=l&&r<=R){return make_pair(maxnum[rt],minnum[rt]);}int m=(l+r)/2;if(R<=m) return query(L,R,lson);else if(L>m) return query(L,R,rson);else{pII leftp=query(L,R,lson);pII rightp=query(L,R,rson);return make_pair( max( leftp.first,rightp.first) , min( leftp.second, rightp.second ) ); }}int dp[maxn];/// seg tree 2int tree2[maxn<<2];void push_up2(int rt){tree2[rt]=min(tree2[rt<<1],tree2[rt<<1|1]);}void build2(){memset(tree2,63,sizeof(tree2));}void insert2(int val,int pos,int l,int r,int rt){if(pos==l&&pos==r){tree2[rt]=val;return ;}int m=(l+r)/2;if(pos<=m) insert2(val,pos,lson);else insert2(val,pos,rson);push_up2(rt);}int query2(int L,int R,int l,int r,int rt){if(L<=l&&r<=R){return tree2[rt];}int m=(l+r)/2;if(R<=m) return query2(L,R,lson);else if(L>m) return query2(L,R,rson);else{int one = query2(L,R,lson);int two = query2(L,R,rson);return min(one,two);}}int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout);scanf("%d%d%d",&n,&s,&l);for(int i=1;i<=n;i++) {dp[i]=INF;scanf("%d",a+i);}build(1,n,1);dp[0]=0; dp[1]=1;if(l>1) dp[1]=INF;build2();insert2(0,0,0,n,1);insert2(1,1,0,n,1);for(int i=2;i<=n;i++){/// binary search to find left boundint low=1,high=i-l+1,leftb=-1;while(low<=high){int mid=(low+high)/2;pII temp = query(mid,i,1,n,1);if(temp.first-temp.second<=s){leftb=mid; high=mid-1;}else low=mid+1;}if(leftb==-1) dp[i]=INF;else{int mmm = query2(leftb-1,i-l,0,n,1);dp[i]=mmm+1;}insert2(dp[i],i,0,n,1);}if(dp[n]>=INF) dp[n]=-1;printf("%d\n",dp[n]); return 0;}
0 0
- Codeforces 487B. Strip DP+线段树+二分
- codeforces 487B B. Strip(rmq+线段树+二分)
- codeforces 488D Strip 线段树+dp+二分
- codeforces 487B Strip dp
- 【DP】 codeforces 487B Strip
- Codeforce 487B Strip 动归+二分+线段树
- Codeforces 487B. Strip(求区间最值+线段树上的dp)
- CodeForces 487B Strip
- codeforces 487 B. Strip
- CodeForces 487B Strip
- Codeforces 487b Strip, dp + RMQ(经典)
- 【Monotonic-queue】【dp】【Segment-tree】【STL】Codeforces 487B - Strip
- CodeForces 487 B.Strip(dp+尺取+set)
- Codeforces 487B Strip(RMQ)
- Codeforces Round #278 (Div. 1) B. Strip(Dp+multiset维护)
- codeforces 573B B. Bear and Blocks(线段树+dp)
- CodeForces 833 B.The Bakery(dp+线段树)
- codeforces.contest/833/problem/B(DP+线段树维护最大值)
- DOM是什么
- 基于特定值来判断隐藏显示元素的jQuery插件
- 计算机是如何工作的?(总结)——三个法宝
- android UI设计的一些心得与问题解决(无效果图)
- Web Storage 数据存储
- Codeforces 487B. Strip DP+线段树+二分
- 解决方案——Connect to an old database using LocalDB in VS
- ejabberd安装步骤+Mysql配置
- MySQL死锁问题实例分析及解决方法
- [LeetCode刷题记录]190-191 Number of 1 Bits & Reverse Bits
- 使用404被动生成缩略图
- CloudFlare resources and downloads
- 内存映射文件
- VC中句柄、指针、ID之间的转换