题意:给定只有黑白两种颜色的序列A,B,每次可以选择一段连续的长度不超过k的区间将其染成同一种颜色,求把序列A变成B所需的最小操作次数。

首先需要找出一些最优解的特征:

1.如果序列A的第一个颜色和B的相同,那么可以忽略掉。如果相反,那么必须将其染成相反的颜色。

2.最优解不会交叉,因为假如出现交叉的话,那么中间交叉的一段相当于做了无用功。

这样就可以进行dp了,将操作从左往右进行,假设前i-1个位置都已经染好了,如果A和B的第i位相同,那么忽略掉,如果相反,那么把它染成相反的颜色,然后只需要考虑右端延伸到哪里的问题。

自己手动模拟一下就会发现,假如B[l,r]一共有x段连续的颜色,那么最少需要$\left\lfloor \frac{x+2}{2}\right\rfloor$次操作就能将A[l,r]染成对应的颜色(在第一次操作将A[l,r]全部染成B[l]的前提下),由此可得递推式:$dp[i]=min\{dp[j]+\left\lfloor \frac{sum(j+1,i)+2}{2}\right\rfloor\},i-k\leqslant j<i$,dp[i]表示将前i个位置染好的最小操作次数。

如何快速求一段区间里的连续颜色段数量呢?区间连续颜色段数量相当于跨过了多少边界,而边界数可以用前缀和S来表示。对于每个位置,如果该位置和它前面位置的颜色不同,那么前缀和+1。这样,区间[l,r]上的连续颜色段数量就等于S[r]-S[l]+1(注意不是S[r]-S[l-1]+1,这里相当于把边权加到了点权上),于是递推式变成了:$\begin{aligned}dp[i]=&min\{dp[j]+\left\lfloor \frac{(S[i]-S[j+1]+1)+2}{2}\right\rfloor\}\\=&min\{dp[j]+\left\lfloor \frac{S[i]-S[j+1]+3}{2}\right\rfloor\}\\=&min\{\left\lfloor \frac{2dp[j]+S[i]-S[j+1]+3}{2}\right\rfloor\}\\=&\left\lfloor \frac{S[i]+min\{2dp[j]-S[j+1]\}+3}{2}\right\rfloor,i-k\leqslant j<i\end{aligned}$

这个递推式可以用滑动窗口+单调队列维护,复杂度$O(n)$

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e5+,inf=0x3f3f3f3f;
int n,k,S[N],dp[N],hd,tl;
char a[N],b[N];
struct D {int x,y;} q[N];
int main() {
scanf("%d%d%s%s",&n,&k,a+,b+);
for(int i=; i<=n; ++i)S[i]=S[i-]+(b[i]!=b[i-]);
dp[]=hd=tl=;
q[tl++]= {,-};
for(int i=; i<=n; ++i) {
for(; hd<tl&&i-q[hd].x>k; ++hd);
dp[i]=a[i]==b[i]?dp[i-]:(S[i]+q[hd].y+)/;
D np= {i,*dp[i]-S[i+]};
for(; hd<tl&&q[tl-].y>=np.y; --tl);
q[tl++]=np;
}
printf("%d\n",dp[n]);
return ;
}

Aizu - 1382 Black or White (分段决策,单调队列优化dp)的更多相关文章

  1. BZOJ_3831_[Poi2014]Little Bird_单调队列优化DP

    BZOJ_3831_[Poi2014]Little Bird_单调队列优化DP Description 有一排n棵树,第i棵树的高度是Di. MHY要从第一棵树到第n棵树去找他的妹子玩. 如果MHY在 ...

  2. 单调队列以及单调队列优化DP

    单调队列定义: 其实单调队列就是一种队列内的元素有单调性的队列,因为其单调性所以经常会被用来维护区间最值或者降低DP的维数已达到降维来减少空间及时间的目的. 单调队列的一般应用: 1.维护区间最值 2 ...

  3. 洛谷P3195 [HNOI2008]玩具装箱TOY(单调队列优化DP)

    题目描述 P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具, ...

  4. 单调队列优化DP,多重背包

    单调队列优化DP:http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 单调队列优化多重背包:http://blog.csdn ...

  5. bzoj1855: [Scoi2010]股票交易--单调队列优化DP

    单调队列优化DP的模板题 不难列出DP方程: 对于买入的情况 由于dp[i][j]=max{dp[i-w-1][k]+k*Ap[i]-j*Ap[i]} AP[i]*j是固定的,在队列中维护dp[i-w ...

  6. hdu3401:单调队列优化dp

    第一个单调队列优化dp 写了半天,最后初始化搞错了还一直wa.. 题目大意: 炒股,总共 t 天,每天可以买入na[i]股,卖出nb[i]股,价钱分别为pa[i]和pb[i],最大同时拥有p股 且一次 ...

  7. Parade(单调队列优化dp)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2490 Parade Time Limit: 4000/2000 MS (Java/Others)    ...

  8. 【单调队列优化dp】 分组

    [单调队列优化dp] 分组 >>>>题目 [题目] 给定一行n个非负整数,现在你可以选择其中若干个数,但不能有连续k个数被选择.你的任务是使得选出的数字的和最大 [输入格式] ...

  9. [小明打联盟][斜率/单调队列 优化dp][背包]

    链接:https://ac.nowcoder.com/acm/problem/14553来源:牛客网 题目描述 小明很喜欢打游戏,现在已知一个新英雄即将推出,他同样拥有四个技能,其中三个小技能的释放时 ...

随机推荐

  1. iostream

    cout 星号*为默认 控制符 描 述 控制符 描 述 *dec 以十进制形式输出整数 hex 以十六进制形式输出整数 oct 以八进制形式输出整数 fixed 以普通小数形式输出浮点数 scient ...

  2. Java学习笔记-枚举类

    实例有限且固定的类成为枚举类 枚举类的实现 早期时候的实现形式: public static final int SEASON_SPRING = 1; public static final int ...

  3. SQL 查询建表SQL

    1.新建一个查询语句,按执行按钮 2.结果页面会显示一条sql语句,复制该语句即可建表 3.建表测试

  4. Nuxt.js入门学习

    Nuxt.js简单的说是Vue.js的通用框架,最常用的就是用来作SSR(服务器端渲染).再直白点说,就是Vue.js原来是开发SPA(单页应用)的,但是随着技术的普及,很多人想用Vue开发多页应用, ...

  5. 【AtCoder】ARC059

    为啥这场ARC那么水--一个点就切完了 ARC059 C - いっしょ / Be Together 枚举就行 #include <bits/stdc++.h> #define fi fir ...

  6. HttpServletResponse对象(转)

    Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象.和代表响应的response对象.request和response对象即然代表请求和响应,那我们要 ...

  7. 微信公众号通过用户授权获取用户基本信息java版

    公司需要开发一个微信公众号,要求用户通过公众号登录公司网站时候自动获取用户的基本信息,在网上查资料发现大部分都是直接copy微信公众平台的开发文档,感觉还是介绍的不是太小白,所以为了方便大家也为了自己 ...

  8. taglib block

    新建文件 package com.augmentum.oes.taglib; import javax.servlet.jsp.JspException; import javax.servlet.j ...

  9. Linux系列之压缩与解压

    1.压缩技术 1.常用命令实例 1.zip格式的压缩与解压缩 zip是压缩指令,unzip是解压指令.zip指令既可以压缩文件,也可以压缩目录.压缩会自动保留源文件,解压会自动保留压缩文件. zip  ...

  10. 1.4Zookeeper和Thymeleaf的使用

    什么是Zookeeper? Zookeeper 是一个开放源码的分布式应用程序协调服务,它包含一个简单的原语集,分布式应用程序可以基于它实现同步服务.配置维护和命名服务等等.采用下图描述zookeep ...