Atcoder CODE FESTIVAL 2017 qual C D - Yet Another Palindrome Partitioning 回文串划分
题目链接
题意
给定一个字符串(长度\(\leq 2e5\)),将其划分成尽量少的段,使得每段内重新排列后可以成为一个回文串。
题解
分析
每段内重新排列后是一个回文串\(\rightarrow\)该段内至多只有一个字符出现过奇数次
考虑哈希到一个\(26\)位的\(01\)串,出现过奇数次的元素位置上的值为\(1\),否则为\(0\).
于是可以继续往下推:\(\rightarrow\)该段的哈希值为\(0\)或者是\(2\)的幂次。
转化
于是问题转化为:将字符串切割成尽量少的若干段,使得每段的哈希值均满足为\(0\)或者是\(2\)的幂次。
预处理异或前缀和可以\(O(1)\)算得每段的哈希值。
问题至此一个很显然的做法就是\(O(n^2)\)的\(dp\),然而显然是无法承受的。
对dp形式的思考
我们来考虑一下原先想写的\(dp\)的形式:
\]
这里的\(ok(j+1,i)\)指的是\(s[j+1..i]\)一段的哈希值满足要求。
仔细思考一下,这里有两个约束条件,
- \(j<i\)
- \(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]\)
所以,我们应该存的信息有:
- \(dp[x]\)代表哈希值为\(x\)的最少切割次数
- \(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 回文串划分的更多相关文章
- 【Atcoder】CODE FESTIVAL 2017 qual C D - Yet Another Palindrome Partitioning
[题意]给定只含小写字母的字符串,要求分割成若干段使段内字母重组顺序后能得到回文串,求最少分割段数.n<=2*10^5 [算法]DP [题解]关键在于快速判断一个字符子串是否合法,容易发现合法仅 ...
- Atcoder CODE FESTIVAL 2017 qual C C - Inserting 'x' 回文串
题目链接 题意 给定字符串\(s\),可以在其中任意位置插入字符\(x\). 问能否得到一个回文串,若能,需插入多少个\(x\). 思路 首先统计出现次数为奇数的字符\(cnt\). \(cnt\ge ...
- Atcoder CODE FESTIVAL 2017 qual B D - 101 to 010 dp
题目链接 题意 对于一个\(01\)串,如果其中存在子串\(101\),则可以将它变成\(010\). 问最多能进行多少次这样的操作. 思路 官方题解 转化 倒过来考虑. 考虑,最终得到的串中的\(' ...
- 题解【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 串 ...
- 【题解】Popping Balls AtCoder Code Festival 2017 qual B E 组合计数
蒟蒻__stdcall终于更新博客辣~ 一下午+一晚上=一道计数题QAQ 为什么计数题都这么玄学啊QAQ Prelude 题目链接:这里是传送门= ̄ω ̄= 下面我将分几个步骤讲一下这个题的做法,大家不 ...
- atcoder/CODE FESTIVAL 2017 qual B/B(dfs染色判断是否为二分图)
题目链接:http://code-festival-2017-qualb.contest.atcoder.jp/tasks/code_festival_2017_qualb_c 题意:给出一个含 n ...
- Atcoder CODE FESTIVAL 2017 qual B E - Popping Balls 组合计数
题目链接 题意 \(A+B\)个球排成一行,左边\(A\)个为红球,右边\(B\)个为蓝球. 最开始可以选择两个数\(s,t\),每次操作可以取左起第\(1\)或\(s\)或\(t\)个球.问有多少种 ...
- Atcoder CODE FESTIVAL 2017 qual B C - 3 Steps 二分图
题目链接 题意 给定一个无向图,\(n\)个点,\(m\)条边(\(n,m\leq 1e5\)). 重复如下操作: 选择相异的两点u,v满足从点u出发走三条边恰好能到达点v.在这样的u,v点对之间添一 ...
- [Atcoder Code Festival 2017 Qual A Problem D]Four Coloring
题目大意:给一个\(n\times m\)的棋盘染四种颜色,要求曼哈顿距离为\\(d\\)的两个点颜色不同.解题思路:把棋盘旋转45°,则\((x,y)<-(x+y,x-y)\).这样就变成了以 ...
随机推荐
- 自动化运维工具——ansible安装入门(一)
一.简介 现如今有很多运维自动化的工具,如:Ansible.Puppet.saltStack.Fabric.chef.Cfengine 1. Ansible介绍 Ansible 是由 Cobbler与 ...
- RPC框架 - thrift 服务端
-------服务端程序 ------ 下载 下载 thrift 源代码包 下载 thrift 的bin包 准备描述文件(使用源代码包的示例文件) \thrift-0.10.0\tu ...
- 科学计算库Numpy——排序
矩阵按维度排序 使用np.sort()进行排序. 排序索引值 使用np.argsort()排序,返回排序后的索引值. 备注:array1[1,2]=1.2,array1[1,0]=5.6,array1 ...
- 什么是redis缓存穿透, 缓存雪崩, 缓存击穿
什么是redis? redis是一个非关系型数据库,相对于其他数据库而言,它的查询速度极快,且能承受的瞬时并发量非常的高.所以常常被用来存放网站的缓存,以减少主要数据库(如mysql)的服务器压力. ...
- [BZOJ1187]神奇游乐园(插头DP)
Description 题意给定一个矩阵,每个格子有权值,在[-1000.1000]内,求一条回路使得回路经过权值和最大,每个格子最多经过一次 2≤n≤100,2≤m≤6 Code #include ...
- spark 对hbase 操作
本文将分两部分介绍,第一部分讲解使用 HBase 新版 API 进行 CRUD 基本操作:第二部分讲解如何将 Spark 内的 RDDs 写入 HBase 的表中,反之,HBase 中的表又是如何以 ...
- VBA连接MySQL数据库以及ODBC的配置(ODBC版本和MySQL版本如果不匹配会出现驱动和应用程序的错误)
db_connected = False '获取数据库连接设置dsn_name = Trim(Worksheets("加载策略").Cells(2, 5).Value) ---- ...
- datetime模块详解
时间运算 >>> datetime.datetime.now() #当前年月 时间datetime.datetime(2018, 2, 13, 16, 12, 6, 850532)& ...
- day23 Model 操作,Form 验证以及序列化操作
Model 操作 1创建数据库表 定制表名: 普通索引: 创建两个普通索引,这样就会生成两个索引文件 联合索引: 为了只生成一个索引文件,才 ...
- 小知识(h5 js )
1.如果都为NaN但是他们不相等var a=NaN;var b=NaN;a==b //flase2.javascript 是一种脚本语言,可以创建服务器端和客户端的脚本3.javascript 中有两 ...