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

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

构造一种删除方案:

除了最先删除的段以外,必然有一时刻(即该段最后一个位置删除时)其余段旁边的两个点颜色都相同,假设都是颜色$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. Java初步学习——2021.09.23每日报告,第三周周四

    (1)今天做了什么: (2)明天准备做什么? (3)遇到的问题,如何解决? 学习数组,编写了一个随机选牌的代码.自己最开始一直想只设置一个字符串数组,利用随机数来输出,但那样对字符串赋值会比较麻烦.可 ...

  2. 题解 「BZOJ3636」教义问答手册

    题目传送门 Description 作为泉岭精神的缔造者.信奉者.捍卫者.传承者,Pear决定印制一些教义问答手册,以满足泉岭精神日益增多的信徒.Pear收集了一些有关的诗选.语录,其中部分内容摘录在 ...

  3. 容器化之路Docker网络核心知识小结,理清楚了吗?

    Docker网络是容器化中最难理解的一点也是整个容器化中最容易出问题又难以排查的地方,加上使用Kubernets后大部分人即使是专业运维如果没有扎实的网络知识也很难定位容器网络问题,因此这里就容器网络 ...

  4. AIbee 笔试

    CSS选择器 div+p 选择紧接在div元素之后的所有< p >元素 C++删除数组最后一个元素. 例如[1 2 3 4] 最后变为 [1 2 3] 用splice的删除,增加和替换 a ...

  5. OO第三次博客作业--第三单元总结

    一.JML 语言的理论基础及应用工具链 JML 是一种行为接口规格语言,提供了对方法和类型的规格定义手段.通过 JML 和其支持工具,不仅可以基于规格自动构造测试用例,并整合了 SMT Solver ...

  6. LP-DDR 和其他 DDR

    一篇技術文檔比較 LP-DDR 和其他 DDR. 就觀念來說,LP-DDR 就是 Low Power 的 DDR:但就架構來說,LP-DDR 和其他 DDR 是截然不同的東西. 他們分屬不同的 JDE ...

  7. 零基础学习Linux必会的60个常用命令

    Linux必学的60个命令Linux提供了大量的命令,利用它可以有效地完成大量的工 作,如磁盘操作.文件存取.目录操作.进程管理.文件权限设定等.所以,在Linux系统上工作离不开使用系统提供的命令. ...

  8. Luogu P1538 迎春舞会之数字舞蹈 | 模拟

    题目链接 大水题,暴力输出,代码应该能看吧...... #include<iostream> #include<cstdio> using namespace std; int ...

  9. cf18B Platforms(仔细谨慎题)

    题意: In one one-dimensional world there are n platforms. Platform with index k (platforms are numbere ...

  10. DeWeb配置SSL的方法,未亲测,供参考

    DeWeb配置SSL的方法1.购买域名的服务商申明免费的SSL证书,然后证书类型下载选择Nginx2.下载Nginx,http://nginx.org/download/nginx-1.20.0.zi ...