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

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

构造一种删除方案:

除了最先删除的段以外,必然有一时刻(即该段最后一个位置删除时)其余段旁边的两个点颜色都相同,假设都是颜色$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.9.23)

         对象:对象是类的一个实例,有状态和行为. 类:类是一个模板,它描述一类对象的行为和状态. 方法:方法就是行为,一个类可以有很多方法. 实例变量:每个对象都有独特的实例变量,对象的状态由这些实 ...

  2. poj1248 (线性筛欧拉函数)(原根)

    强烈鸣谢wddwjlss 题目大意:给出一个奇素数,求出他的原根的个数,多组数据. 这里先介绍一些基本性质 阶 设\((a,m)=1\),满足\(a^r \equiv 1 \pmod m\)的最小正整 ...

  3. 【转载】[经验] 嵌入式stm32实用的排序算法 - 交换排序

    Ⅰ.写在前面 前面写了关于ADC采集电压的文章,大家除了求平均的方式来处理采样值,还有没有使用到其他的方式来处理采集值呢? 在某些情况下就需要对一组数据进行排序,并提取头特定的数据出来使用. 排序的应 ...

  4. 【UE4 C++】读写Text文件 FFileHelper

    CoreMisc.h 读取 FFileHelper::LoadFileToString 读取全部内容,存到 FString FString TextPath = FPaths::ProjectDir( ...

  5. [no_code][Alpha]项目展示博客

    $( "#cnblogs_post_body" ).catalog() 团队项目链接 github 后端 github OCR文档-含部分所需测试代码目前private API调用 ...

  6. 2021.10.7 NKOJ周赛总结

    Ⅰ. 自描述序列 问题描述: 序列 1,2,2,1,1,2,1,2,2,1,2,2,1,1,2,1,1,2,2,1,... 看似毫无规律,但若我们将相邻的数字合并 : 1,22,11,2,1,22,1 ...

  7. 基于Vue的工作流项目模块中,使用动态组件的方式统一呈现不同表单数据的处理方式

    在基于Vue的工作流项目模块中,我们在查看表单明细的时候,需要包含公用表单信息,特定表单信息两部分内容.前者表单数据可以统一呈现,而后者则是不同业务的表单数据不同.为了实现更好的维护性,把它们分开作为 ...

  8. 用C++实现的数独解题程序 SudokuSolver 2.6 的新功能及相关分析

    SudokuSolver 2.6 的新功能及相关分析 SudokuSolver 2.6 的命令清单如下: H:\Read\num\Release>sudoku.exe Order please: ...

  9. Gitee图床设置

    https://gitee.com/ 创建新仓库 点击右上角加号->新建仓库,填写基本信息后点击下面的创建即可 https://gitee.com/projects/new 创建新令牌 点击设置 ...

  10. python3 调用 centos 常用系统命令

    一.创建目录 1 import os 2 3 base_path = '/data/sw_backup' 4 addr= 'FT' 5 ip='192.168.1.1' 6 path = base_p ...