题目链接

题意

给定一个字符串(长度\(\leq 2e5\)),将其划分成尽量少的段,使得每段内重新排列后可以成为一个回文串。

题解

分析

每段内重新排列后是一个回文串\(\rightarrow\)该段内至多只有一个字符出现过奇数次

考虑哈希到一个\(26\)位的\(01\)串,出现过奇数次的元素位置上的值为\(1\),否则为\(0\).

于是可以继续往下推:\(\rightarrow\)该段的哈希值为\(0\)或者是\(2\)的幂次。

转化

于是问题转化为:将字符串切割成尽量少的若干段,使得每段的哈希值均满足为\(0\)或者是\(2\)的幂次

预处理异或前缀和可以\(O(1)\)算得每段的哈希值。

问题至此一个很显然的做法就是\(O(n^2)\)的\(dp\),然而显然是无法承受的。

对dp形式的思考

我们来考虑一下原先想写的\(dp\)的形式:

\[dp[i]=min_{j<i,ok(j+1,i)}\{dp[j]\}+1
\]

这里的\(ok(j+1,i)\)指的是\(s[j+1..i]\)一段的哈希值满足要求。

仔细思考一下,这里有两个约束条件,

  1. \(j<i\)
  2. \(ok(j+1,i)\)

我们常规的思路是拿第一个条件去循环,然后判断第二个条件是否被满足。

然而在这里,对于给定的\(i\),有\(i-1\)个\(j\)满足第一个条件,而只有\(\leq 27\)个\(j\)满足第二个条件。

更优的考虑是拿第二个条件去循环。

O(n)-dp

什么叫做拿第二个条件去循环呢?

意思是我们直接找到那个\(h[j]\),它和\(h[i]\)异或起来的值满足条件。

由异或的性质,\(h[i]\oplus h[j]=power\leftrightarrow h[i]\oplus power=h[j]\)

所以,我们应该存的信息有:

  1. \(dp[x]\)代表哈希值为\(x\)的最少切割次数
  2. \(opt[i]\)代表\([1..i]\)段最少的切割次数

则显然转移有$$opt[i]=min{dp[h[i]\oplus mask]}+1$$$$dp[x]=min(dp[x],opt[i])$$

官方题解

Code

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define maxn 200010
using namespace std;
typedef long long LL;
char s[maxn];
int opt[maxn], h[maxn];
int main() {
scanf("%s", s+1);
int len = strlen(s+1);
for (int i = 1; i <= len; ++i) h[i] = h[i-1] ^ (1<<(s[i]-'a'));
map<int, int> dp;
for (int i = 1; i <= len; ++i) {
opt[i] = (!h[i] || dp[h[i]]) ? dp[h[i]] : inf;
int mask = 1;
for (int j = 0; j < 26; ++j) {
if ((h[i]^mask) == 0 || dp[h[i]^mask]) opt[i] = min(opt[i], dp[h[i]^mask]);
mask <<= 1;
}
++opt[i];
if (!dp[h[i]] && h[i]) dp[h[i]] = opt[i];
else dp[h[i]] = min(dp[h[i]], opt[i]);
}
printf("%d\n", opt[len]);
return 0;
}

Atcoder CODE FESTIVAL 2017 qual C D - Yet Another Palindrome Partitioning 回文串划分的更多相关文章

  1. 【Atcoder】CODE FESTIVAL 2017 qual C D - Yet Another Palindrome Partitioning

    [题意]给定只含小写字母的字符串,要求分割成若干段使段内字母重组顺序后能得到回文串,求最少分割段数.n<=2*10^5 [算法]DP [题解]关键在于快速判断一个字符子串是否合法,容易发现合法仅 ...

  2. Atcoder CODE FESTIVAL 2017 qual C C - Inserting 'x' 回文串

    题目链接 题意 给定字符串\(s\),可以在其中任意位置插入字符\(x\). 问能否得到一个回文串,若能,需插入多少个\(x\). 思路 首先统计出现次数为奇数的字符\(cnt\). \(cnt\ge ...

  3. Atcoder CODE FESTIVAL 2017 qual B D - 101 to 010 dp

    题目链接 题意 对于一个\(01\)串,如果其中存在子串\(101\),则可以将它变成\(010\). 问最多能进行多少次这样的操作. 思路 官方题解 转化 倒过来考虑. 考虑,最终得到的串中的\(' ...

  4. 题解【AtCoder - CODE FESTIVAL 2017 qual B - D - 101 to 010】

    题目:https://atcoder.jp/contests/code-festival-2017-qualb/tasks/code_festival_2017_qualb_d 题意:给一个 01 串 ...

  5. 【题解】Popping Balls AtCoder Code Festival 2017 qual B E 组合计数

    蒟蒻__stdcall终于更新博客辣~ 一下午+一晚上=一道计数题QAQ 为什么计数题都这么玄学啊QAQ Prelude 题目链接:这里是传送门= ̄ω ̄= 下面我将分几个步骤讲一下这个题的做法,大家不 ...

  6. atcoder/CODE FESTIVAL 2017 qual B/B(dfs染色判断是否为二分图)

    题目链接:http://code-festival-2017-qualb.contest.atcoder.jp/tasks/code_festival_2017_qualb_c 题意:给出一个含 n ...

  7. Atcoder CODE FESTIVAL 2017 qual B E - Popping Balls 组合计数

    题目链接 题意 \(A+B\)个球排成一行,左边\(A\)个为红球,右边\(B\)个为蓝球. 最开始可以选择两个数\(s,t\),每次操作可以取左起第\(1\)或\(s\)或\(t\)个球.问有多少种 ...

  8. Atcoder CODE FESTIVAL 2017 qual B C - 3 Steps 二分图

    题目链接 题意 给定一个无向图,\(n\)个点,\(m\)条边(\(n,m\leq 1e5\)). 重复如下操作: 选择相异的两点u,v满足从点u出发走三条边恰好能到达点v.在这样的u,v点对之间添一 ...

  9. [Atcoder Code Festival 2017 Qual A Problem D]Four Coloring

    题目大意:给一个\(n\times m\)的棋盘染四种颜色,要求曼哈顿距离为\\(d\\)的两个点颜色不同.解题思路:把棋盘旋转45°,则\((x,y)<-(x+y,x-y)\).这样就变成了以 ...

随机推荐

  1. 如何查看连接到手机热点的ip地址

    因为最近玩树莓派,需要手机做热点,然后用树莓派连接到这个热点上,苦于不知道树莓派被分配了什么样的ip地址,经过一番探索,我发现了两种办法, 安装一个 android terminal( 安卓命令行), ...

  2. Visual Studio-IIS Express 支持局域网访问配置

    转自:http://www.itnose.net/detail/6132793.html 注意:本人测试后,发现个问题,不知是我个人的VS问题还是普遍的.就是将配置文件中的新增的节点注释后,会导致页面 ...

  3. (HTML)A标签伪元素选择器的继承关系

    ①如果a:link{}也存在,那么不管a{}放到哪里,a{}和a:link{}冲突的属性都会采用a:link{}的,不冲突的属性若存在a{}中,会被a:link{}. a:visited{} .a:h ...

  4. Diycode开源项目 ImageActivity分析

    1.首先看一下效果 1.1做成了一个GIF 1.2.我用格式工厂有点问题,大小无法调到手机这样的大小,目前还没有解决方案. 1.3.网上有免费的MP4->GIF,参考一下这个网站吧. 1.4.讲 ...

  5. jmeter全局变量配置:将token运用到全局(跨线程组使用变量)

    请注意元器件的执行顺序: 请将提取token的配置原件放在设置全局变量的配置元器件前面(本来是一个超级马虎的人,真是俗称“方脑壳”啊) 1.获取登录后的token(提取可以用json path Ext ...

  6. Normal synchronous FIFO mode 和 Show-ahead synchronous FIFO mode

    FIFO是先进先出,可以用fifo来处理跨时钟域的数据传输问题,用到的地方特别多,一定要搞会. 在学习调用fifo的IP核中发现有normal synchronous FIFO mode 和 Show ...

  7. [oldboy-django][2深入django]学生管理(Form)-- 编辑(设置input标签属性,设置input标签默认显示值,设置input的类型)

    1 django 后台实现设置input标签属性,设置input标签默认显示值,设置input输入框类型 # Form生成html标签 a. 通过Form生成Input输入框,Form标签,以及sub ...

  8. linux文件备份到windows方法

    目录 背景 方案 过程记录 在windows上创建共享目录 将windows上共享的目录绑定到/mnt目录下 问题处理 背景 需编写部门wiki备份数据脚本.但wiki部署在linux上,而需将备份数 ...

  9. PHP排序的几种方法

    // 冒泡排序 function BubbleSort($arr) { // 获得数组总长度 $num = count($arr); // 正向遍历数组 for ($i = 1; $i < $n ...

  10. 关于JavaWeb开发的一些感悟

    从事JavaWeb的开发已经三年了,从最开始的啥都不会,到慢慢的能够独立做项目,从一开始的一片茫然,到现在的心中有数.对于技术.业务也有了自己的看法. JavaWeb开发所涉及到的知识点非常多,涉及到 ...