题目链接

题意

给定一个字符串(长度\(\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;
}

最新文章

  1. (转)pymysql 连接mysql数据库---不支持中文解决
  2. POJ 3415 Common Substrings 后缀数组+并查集
  3. android: 播放视频
  4. android获取设备全部信息
  5. 1 Winform 异步更新控件
  6. Risk(最短路)
  7. JavaScript之函数作用域
  8. git 使用总结
  9. 深入理解Oracle中的随机函数
  10. 怎么确定Oracle客户端安装成功
  11. 如何验证代理ip的正确性
  12. Topic Model的分类和设计原则
  13. Tomcat------如何打开配置界面
  14. Servlet之javax.servlet包
  15. 【LeetCode题解】141_环形链表
  16. Elasticsearch部分节点不能发现集群(脑裂)问题处理
  17. spark配置文件和执行部分代码
  18. .Net程序随系统开机启动(仿Foxmail托盘效果控制)
  19. mysql5.7
  20. tomcat6升级到7时400问题,以及url带有汉字时出错。

热门文章

  1. Linux常用关机重启命令
  2. 16.2--Jenkins+Maven+Gitlab+Tomcat 自动化构建打包、部署
  3. 【PHP】PHP中的排序函数sort、asort、rsort、krsort、ksort区别分析
  4. JZOJ 5793. 【NOIP2008模拟】小S练跑步
  5. JZOJ 3382. 【NOIP2013模拟】七夕祭
  6. Python中列表的深浅拷贝
  7. Green Space【绿色空间】
  8. James Bach Rapid Test的感受
  9. HDU1042 A * B Problem Plus
  10. 高亮T4模板