2015 ACM Amman Collegiate Programming Contest L.Alternating StringsII
来源:互联网 发布:c语言线程同算法 编辑:程序博客网 时间:2024/06/08 07:09
题目大意:
给你长度为N的一个01字符串,要求我们将其割分成若干个连续子序列,使得每个子序列的长度都不超过K,而且保证每个子序列,要么是单独的一个数,要么是非01间差排列的子序列(01间差排列:1010,010101,.....................)。
思路:
我们通过做这套题的D题的时候不难发现,对于可以割开的字符串,其具有单调性,显然字符串越长,越可能作为割分的子序列(就是非01间差排列的字符串).
我们设定Dp【i】,表示以i作为结尾的时候,需要割分的最小次数,那么显然有:
①Dp【i】=min(Dp【j】+1,Dp【i】);需要保证从j+1到位子i的排列是可行方案。
②Dp【i】=min(Dp【i-1】+1,Dp【i】);
考虑到①中,可行方案的位子具有单调性,所以我们二分一个点,使得这个点是从右往左扫,第一个构成可行方案的位子。
那么我们有:Dp【i】=min(Dp【i】,Dp【j】)【max(i-k,0)<=j<=pos】;
然后我们套个线段树加速转移即可。
时间复杂度O(nlogn)
Ac代码:
#include<stdio.h>#include<string.h>#include<iostream>using namespace std;const int INF=0x3f3f3f3f;int sum[105550*5],lazy[105550*5];void pushup(int rt){ sum[rt]=min(sum[rt<<1],sum[rt<<1|1]);}void pushdown(int rt){ if(lazy[rt]){ lazy[rt<<1]+=lazy[rt]; lazy[rt<<1|1]+=lazy[rt]; sum[rt<<1]+=lazy[rt]; sum[rt<<1|1]+=lazy[rt]; lazy[rt]=0; }}void build(int rt,int l,int r){ lazy[rt]=sum[rt]=0; if(l==r) {sum[rt]=0;return ;} int m = r+l >> 1; build(rt<<1 ,l ,m); build(rt<<1|1,m+1,r); pushup(rt);}void update(int rt,int l,int r,int L,int R,int v){ if(L<=l&&r<=R){ lazy[rt]+=v; sum[rt]+=v; return ; } pushdown(rt); int m = r+l >> 1; if(L<=m) update(rt<<1 ,l ,m,L,R,v); if(R> m) update(rt<<1|1,m+1,r,L,R,v); pushup(rt);}int query(int rt,int l,int r,int L,int R){ if(L<=l&&r<=R) return sum[rt]; pushdown(rt); int m = r+l >> 1,ans = INF; if(L<=m) ans = min(ans,query(rt<<1 ,l ,m,L,R)); if(R> m) ans = min(ans,query(rt<<1|1,m+1,r,L,R)); pushup(rt); return ans;}int temp[150000];int dp[150000];char a[150000];int main(){ int t; scanf("%d",&t); while(t--) { int n,k; scanf("%d%d",&n,&k); scanf("%s",a+1); dp[0]=0; memset(temp,0,sizeof(temp)); for(int i=1;i<=n;i++)dp[i]=0x3f3f3f3f; for(int i=n;i>=1;i--) { int cnt=0; if(a[i]==a[i+1])cnt=1; if(i==n)temp[i]=0; else temp[i]=temp[i+1]+cnt; } temp[0]=temp[1]; build(1,0,n); for(int i=1;i<=n;i++) { dp[i]=min(dp[i],dp[i-1]+1); int l=max(i-k+1-1,0); int r=i-1; int pos=-1; while(r-l>=0) { int mid=(l+r)/2; if(temp[mid+1]-temp[i]>0) { pos=mid; l=mid+1; } else r=mid-1; } if(pos!=-1)dp[i]=min(dp[i],query(1,0,n,max(i-k,0),pos)+1); update(1,0,n,i,i,dp[i]); } printf("%d\n",dp[n]-1); }}
阅读全文
0 0
- 2015 ACM Amman Collegiate Programming Contest L.Alternating StringsII
- 2015 ACM Amman Collegiate Programming Contest L .Alternating Strings II
- 2015 ACM Amman Collegiate Programming Contest D.Alternating Strings【Dp】
- Codeforces Gym 2015 ACM Amman Collegiate Programming Contest
- 2015 ACM Amman Collegiate Programming Contest 简要题解。
- 2015 ACM Amman Collegiate Programming Contest训练总结【12/12】
- 2017 ACM Amman Collegiate Programming Contest
- 2017 ACM Amman Collegiate Programming Contest J
- GYM 2017 ACM Amman Collegiate Programming Contest
- 2016 ACM Amman Collegiate Programming Contest 训练赛部分题解
- ACM Amman Collegiate Programming Contest C. Street Lamps
- 2017 ACM Amman Collegiate Programming Contest-补题-H
- 2015 ACM Amman Collegiate Programming Contest I.Bahosain and Digits【思维+暴力枚举】
- 2015 ACM Amman Collegiate Programming Contest H.Bridges【边双联通+求树上最长链(树的直径)】
- GYM 2015 ACM Syrian Collegiate Programming Contest
- 2015 ACM Arabella Collegiate Programming Contest(F题)
- Codeforces Gym 2015 ACM Arabella Collegiate Programming Contest
- 2017 ACM Arabella Collegiate Programming Contest-L. All’s Wall That Ends Wall
- linux通信 进程间通信有哪几种方式?
- SDRAM控制模块图
- restful理解
- 自行准备深度学习训练数据
- 数据结构学习笔记2
- 2015 ACM Amman Collegiate Programming Contest L.Alternating StringsII
- Hadoop新版本中map任务待处理split大小的计算方法
- radosgw 各个pool作用及联系
- 【selenium】python+selenium+unittest,关于每次执行完一个测试用例都关闭浏览器等时间较长的问题之解决方案
- days4
- java学习随笔
- TensorFlow 智能机器人原理与实现
- 接下来做的几个案例
- HDU 3038How Many Answers Are Wrong