题目链接

题意

给定一个字符串(长度\(\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. 十、Linux vi/vim

    Linux vi/vim 所有的 Unix Like 系统都会内建 vi 文书编辑器,其他的文书编辑器则不一定会存在. 但是目前我们使用比较多的是 vim 编辑器. vim 具有程序编辑的能力,可以主 ...

  2. Linux问题分析或解决_samba无法连接

    1. windows设置方面问题 问题:window能连接部分服务器的samba共享,一部分无法连接.报错如截图. 解决:前提---其他人连接都没有问题,发现有问题的连接服务器的电脑是win10,而w ...

  3. linux 编辑文档

    本篇主要分享下vi 命令行的操作: vi  /etc/sysconfig/iptabels 首先我们需要理解putty客户端的复制 粘贴 插入文档  退出等命令 复制:指在putty客户端中的选择复制 ...

  4. 卸载Redhat 7自带的yum,安装并使用网易163源

    由于redhat的yum在线更新是收费的,如果没有注册的话不能使用,如果要使用,需将redhat的yum卸载后,安装CentOS yum工具,再配置其他源,以下为详细过程:删除redhat原有的yum ...

  5. LRU算法原理解析

    LRU是Least Recently Used的缩写,即最近最少使用,常用于页面置换算法,是为虚拟页式存储管理服务的. 现代操作系统提供了一种对主存的抽象概念虚拟内存,来对主存进行更好地管理.他将主存 ...

  6. Linux命令之---ls

    命令简介: ls(list)命令用来列出目标目录(缺省的话为当前目录)中所有的子目录和文件. 指令所在路径:/bin/ls 执行权限:All User 命令语法: ls [选项] [目录名] 命令参数 ...

  7. 推荐Android几个优质的完整项目学习

    ==>来自于微信公众号==鸿洋.大家可以关注一波大神之作. 后台经常有人问我能不能推荐几个完整项目用于学习.借着周末的机会,给大家推荐几个,项目我基本都在本地运行过,并且会在文章末尾提供每个项目 ...

  8. Go语言之并发编程(二)

    通道(channel) 单纯地将函数并发执行是没有意义的.函数与函数间需要交换数据才能体现并发执行函数的意义.虽然可以使用共享内存进行数据交换,但是共享内存在不同的goroutine中容易发生竞态问题 ...

  9. Spring MVC学习总结

    Spring MVC学习总结 Spring MVC学习路(一) 下载配置文件 Spring MVC学习路(二) 设置配置文件 Spring MVC学习路(三) 编写第一个demo Spring MVC ...

  10. 使用 Item,ItemManager 在 XNA 中创建物品和道具(十六)

    平方已经开发了一些 Windows Phone 上的一些游戏,算不上什么技术大牛.在这里分享一下经验,仅为了和各位朋友交流经验.平方会逐步将自己编写的类上传到托管项目中,没有什么好名字,就叫 WPXN ...