考虑最终有石子的位置的状态,判断一种状态是否可行

反过来,依次删除石子,删除条件是:当删除的石子是该段最后一个(即其两边都没有石子了),要求除其以外,每个连续段旁边的两个点都与其颜色不同

构造一种删除方案:

除了最先删除的段以外,必然有一时刻(即该段最后一个位置删除时)其余段旁边的两个点颜色都相同,假设都是颜色$c$,另外一种颜色为$c'$

接下来,如果一个段内含有$c'$,那么必然可以直接删除该段且不劣,因此我们删除了所有含有$c'$的段

而对于剩下的段,其所有位置以及旁边都为颜色$c$,那么若有超过1段,则一定不合法,因此我们要让段尽量长(以包含$c'$来删除),即在构造段旁边颜色为$c$时,找到第一个$c$即可

总结一下,考虑合法当且仅当存在颜色$c$,满足以下条件:

1.对于最先删除的段,其中包含颜色$c'$

2.对于最晚删除的段,其与其旁边的位置包含至少两个$c$(即含有$cc$的子序列)

3.对于其余的段,其与其旁边的位置包含一个$cc'c$的子序列

(特别的,如果仅有1个段必然是可行的)

先枚举颜色$c$,对每一个颜色$c$求出最短的方案再取min即可

考虑dp,用$f_{i,j,0/1,0/1}$表示前$i$个字母,$i$所处的串状态为$j$,是否已经出现要强制最先删除/最后删除的段(不包括$i$所处的段)的最短长度,向后转移即可

状态$j$的定义方式有很多,只需要能够转移、能够确定该串的类型即可(例如与$cc'c$的最长公共子序列长度/未被选择)

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 100005
4 #define get_min(x,y) x=min(x,y)
5 int n,ans,f[N][5][2][2];
6 char s[N],t[N];
7 int calc(){
8 memset(f,0x3f,sizeof(f));
9 f[0][0][0][0]=0;
10 for(int i=0;i<=n;i++)
11 for(int j=0;j<5;j++)
12 for(int p=0;p<2;p++)
13 for(int q=0;q<2;q++){
14 if (t[i+1]=='_'){//不选
15 if (!j)get_min(f[i+1][0][p][q],f[i][j][p][q]);
16 if (((j==2)||(j==3))&&(!p)&&(s[i+1]=='w'))get_min(f[i+1][0][1][q],f[i][j][p][q]);
17 if ((j==3)&&(s[i+1]=='w')||(j==4))get_min(f[i+1][0][p][q],f[i][j][p][q]);
18 }
19 int jj=max(j,1);
20 if ((jj==1)&&(s[i]=='w'))jj=2;
21 if ((jj==2)&&(s[i+1]=='b'))jj=3;
22 if ((jj==3)&&(s[i+1]=='w'))jj=4;
23 get_min(f[i+1][jj][p][q],f[i][j][p][q]+1);
24 if (!p){
25 int jj=max(j,1);
26 if ((jj==1)&&(s[i]=='w'))jj=2;
27 if ((jj==2)&&(s[i+1]=='b'))jj=3;
28 if ((j>=2)&&((jj==2)||(jj==3))&&(s[i+1]=='w'))jj=4;
29 get_min(f[i+1][jj][1][q],f[i][j][p][q]+1);
30 }
31 if (!q){
32 int jj=max(j,1);
33 if ((jj==1)&&(s[i]=='w'))jj=2;
34 if ((jj<=3)&&(s[i+1]=='b'))jj=4;
35 if ((jj==3)&&(s[i+1]=='w'))jj=4;
36 get_min(f[i+1][jj][p][1],f[i][j][p][q]+1);
37 }
38 }
39 for(int i=0;i<2;i++)
40 for(int j=0;j<2;j++)ans=min(ans,min(f[n+1][0][i][j],f[n+1][4][i][j]));
41 }
42 int main(){
43 scanf("%d%s%s",&n,s+1,t+1);
44 int x=0,y=0;
45 for(int i=1;i<=n;i++)
46 if (t[i]=='o'){
47 if (!x)x=i;
48 y=i;
49 }
50 t[n+1]='_';
51 ans=y-x+1;
52 s[0]='w';
53 s[n+1]='b';
54 calc();
55 for(int i=0;i<=n+1;i++)
56 if (s[i]=='w')s[i]='b';
57 else s[i]='w';
58 calc();
59 printf("%d",ans);
60 }

[atARC109F]1D Kingdom Builder的更多相关文章

  1. ARC109F - 1D Kingdom Builder

    一行格子,其中小于\(0\)的格子为白色,大于\(n\)的格子为黑色,中间的格子颜色由题目给出. 有一些格子需要被标记.标记按照以下规则进行:选择一个颜色\(c\),找到一个未标记的 旁边有标记点的 ...

  2. [atARC109E]1D Reversi Builder

    归纳每一次操作后必然是两个颜色相同的连续段(即ww...bb...或bb...ww...),对操作的位置分类讨论不难证明正确性 当$c_{1}=c_{n}$,由于端点颜色不会修改,再根据该结论,可以得 ...

  3. AtCoder Regular Contest 109

    Contest Link 为什么还没有 Official Editorial 啊--哦,原来是日文题解,那没事了. A - Hands 有两幢 100 层的楼房 \(A,B\) ,将地面所在的楼层称为 ...

  4. TDictionary 是delphi用的,c++builder用起来太吃力。

    TDictionary 是delphi用的,c++builder用起来太吃力.c++还是用std::map代替.c++d map很好用啊.https://blog.csdn.net/ddkxddkx/ ...

  5. 23种设计模式--建造者模式-Builder Pattern

    一.建造模式的介绍       建造者模式就是将零件组装成一个整体,用官方一点的话来讲就是将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示.生活中比如说组装电脑,汽车等等这些都是建 ...

  6. PHP设计模式(五)建造者模式(Builder For PHP)

    建造者模式:将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示的设计模式. 设计场景: 有一个用户的UserInfo类,创建这个类,需要创建用户的姓名,年龄,爱好等信息,才能获得用 ...

  7. 每天一个设计模式-7 生成器模式(Builder)

    每天一个设计模式-7 生成器模式(Builder) 一.实际问题 在讨论工厂方法模式的时候,提到了一个导出数据的应用框架,但是并没有涉及到导出数据的具体实现,这次通过生成器模式来简单实现导出成文本,X ...

  8. Stack Overflow 排错翻译 - Closing AlertDialog.Builder in Android -Android环境中关闭AlertDialog.Builder

    Stack Overflow 排错翻译  - Closing AlertDialog.Builder in Android -Android环境中关闭AlertDialog.Builder 转自:ht ...

  9. Joshua Bloch错了? ——适当改变你的Builder模式实现

    注:这一系列都是小品文.它们偏重的并不是如何实现模式,而是一系列在模式实现,使用等众多方面绝对值得思考的问题.如果您仅仅希望知道一个模式该如何实现,那么整个系列都会让您失望.如果您希望更深入地了解各个 ...

随机推荐

  1. SpringBoot+WebSocket实时监控异常

    写在前面 此异常非彼异常,标题所说的异常是业务上的异常. 最近做了一个需求,消防的设备巡检,如果巡检发现异常,通过手机端提交,后台的实时监控页面实时获取到该设备的信息及位置,然后安排员工去处理. 因为 ...

  2. Java(8)详解Random使用

    作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15201556.html 博客主页:https://www.cnblogs.com/testero ...

  3. 这部分布式事务开山之作,凭啥第一天预售就拿下当当新书榜No.1?

    大家好,我是冰河~~ 今天,咱们就暂时不聊[精通高并发系列]了,今天插播一下分布式事务,为啥?因为冰河联合猫大人共同创作的分布式事务领域的开山之作--<深入理解分布式事务:原理与实战>一书 ...

  4. SingnalR 从开发到生产部署闭坑指南

    前天倒腾了一份[SignalR在react/go技术栈的实践], 步骤和思路大部分是外围框架的应用, 今天趁热打铁, 给一个我总结的SignalR避坑指南. 1.SignalR 默认协商 不管是.NE ...

  5. I-Base62

    I - Base62 PS:一个任意进制转换的大数问题 传送门:Base62 短除法原理: 20(10进制) => 202(3进制) 20 = (2 * 3 ^ 2 + 0 * 3 ^ 1 + ...

  6. 【UE4 设计模式】原型模式 Prototype Pattern

    概述 描述 使用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.如孙悟空猴毛分身.鸣人影之分身.剑光分化.无限剑制 原型模式是一种创建型设计模式,允许一个对象再创建另外一个可定制的对象, ...

  7. RabbitMQ的一些理解和笔记

    在这篇博客中,简单记录一下 rabbitmq 服务器中一些基本的概念. Connection: connection 为 TCP连接,是我们的应用程序和RabbitMQ服务器真正发送和接收数据的地方. ...

  8. python的random模块生成随机数

    python的random函数 random.random() 生成0-1之间的随机数 random.uniform(a,b)生成a,b之间的浮点数 random.randint(a,b)生成a,b之 ...

  9. Docker 安装 MySQL8

    1. 环境准备 创建挂载数据目录和配置文件 mkdir -p /mnt/mysql/data /etc/mysql/conf touch /etc/mysql/conf/my.cnf 2. 拉取镜像 ...

  10. stat命令的实现

    任务详情 学习使用stat(1),并用C语言实现 提交学习stat(1)的截图 man -k ,grep -r的使用 伪代码 产品代码 mystate.c,提交码云链接 测试代码,mystat 与st ...