题目大意:

把一个字符串s分割成m个串,这m个串满足至多有一种字符出现次数为奇数次,其他均为偶数次,问m的最小值

题解:

首先我们想一下纯暴力怎么做

显然是可以n^2暴力的,然后dp[i]表示分割到i的所用最少的串个数

接下来就是枚举所有可行的j,使得dp[j]转移到dp[i]。

虽然可以暴力找,但是如果使用暴力找,则后续就无法优化了,这里就用到了异或的思想

用一个26位的int数组a[i]表示从1到i的状态,第j位为1代表这个字母出现了奇数次,反之为偶数次。

那么区间[l, r]是否可行,就是a[l]^a[r]的值必须为2的幂次。

有了这个性质,转移依然是n^2的,但是我们可以优化它。

dp[i][x]表示1~i中当前状态为x,分割到i所用最少的串个数。

那么考虑如何更新i+1,首先i+1的状态是固定的,就是a[i]。

所以能更新的就是所有使得y^a[i]是2的幂次的y,dp[i][a[i]] = min(dp[i][a[i]], dp[i-1][y])。

注意异或是可交换,那么只需要枚举2的幂次,然后和a[i]异或,就可以得到y了

于是就这么神奇的做完了!

复杂度O(26*n)

题解很麻烦,但是代码量是很少的。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 2e5 + ;
char str[maxn];
int a[maxn];
int dp[(<<)];
int main()
{
cin>>str;
int L = strlen(str), ans = ;
for(int i = ; i < L; i++){
ans ^= (<<(str[i] - 'a'));
a[i] = ans;
}
memset(dp, , sizeof(dp));
for(int i = ; i < L; i++){
int ok = ;
for(int j = ; j < ; j++) if(a[i] == || (a[i]^(<<j)) == ) { dp[a[i]] = ; ok = ; break; }
if(ok) continue;
for(int j = ; j < ; j++)
dp[a[i]] = min(dp[a[i]^(<<j)]+, dp[a[i]]);
}
cout<<dp[a[L-]]<<endl;
return ;
}

atcoder 2017Code festival C ——D题 Yet Another Palindrome Partitioning(思维+dp)的更多相关文章

  1. 【leetcode刷题笔记】Palindrome Partitioning II

    Given a string s, partition s such that every substring of the partition is a palindrome. Return the ...

  2. 【leetcode刷题笔记】Palindrome Partitioning

    Given a string s, partition s such that every substring of the partition is a palindrome. Return all ...

  3. Atcoder CODE FESTIVAL 2016 Grand Final E - Water Distribution

    Atcoder CODE FESTIVAL 2016 Grand Final E - Water Distribution 题目链接:https://atcoder.jp/contests/cf16- ...

  4. [AtCoder Code Festival 2017 QualB D/At3575] 101 to 010 - dp

    [Atcoder Code Festival 2017 QualB/At3575] 101 to 010 有一个01序列,每次可以选出一个101,使其变成010,问最优策略下能操作几次? 考虑像 11 ...

  5. Atcoder Yet Another Palindrome Partitioning(状压dp)

    Atcoder Yet Another Palindrome Partitioning 思路: 一个字符串满足条件的情况是奇数字母个数小于等于1,也就是异或起来是1<<j(0<=j& ...

  6. Atcoder CODE FESTIVAL 2016 qual C 的E题 Encyclopedia of Permutations

    题意: 对于一个长度为n的排列P,如果P在所有长度为n的排列中,按照字典序排列后,在第s位,则P的value为s 现在给出一个长度为n的排列P,P有一些位置确定了,另外一些位置为0,表示不确定. 现在 ...

  7. Atcoder Code Festival 2017 qual C 10.22 D题题解

    [题意概述] 给出一个只有小写字母的序列,问最少把序列分成几段可以满足每一段可以通过变换成为回文串.变换指的是交换子序列中的字母的位置. [题解] 我们把a~z分别设为2^0~2^25,每个子序列满足 ...

  8. AtCoder Beginner Contest 069 ABCD题

    题目链接:http://abc069.contest.atcoder.jp/assignments A - K-City Time limit : 2sec / Memory limit : 256M ...

  9. AtCoder Beginner Contest 068 ABCD题

    A - ABCxxx Time limit : 2sec / Memory limit : 256MB Score : 100 points Problem Statement This contes ...

随机推荐

  1. day7 RHCE

    6.配置本地邮件服务 在系统server0和desktop0上配置邮件服务,满足以下要求:这些系统不接收外部发送来的邮件这些系统上本地发送的任何邮件都会自动路由到 classroom.example. ...

  2. 质造未来,首届腾讯WeTest技术交流开放日成功举办

    WeTest 导读 北京时间12月21日下午1点整,2018年度腾讯WeTest技术交流开放日在上海举办.盛大.巨人.电魂.bilibili.方趣等十余家来自不同优秀企业的测试技术负责人均来到现场,共 ...

  3. 利用PreparedStatement预防SQL注入

    1.什么是sql注入 SQL 注入是用户利用某些系统没有对输入数据进行充分的检查,从而进行恶意破坏的行为. 例如登录用户名采用  ' or 1=1 or username=‘,后台数据查询语句就变成 ...

  4. springmvc传参---LocalDateTime、Date等时间类型转换

    此处定义的dateConvert用来转换Date类型,如果是LocalDate.LocalDateTime类型,则将Date类型换成相应的类型即可,注意java8的日期类型需要用Formatter格式 ...

  5. shell 判断日期间隔及润年

    #!/bin/bash test.sh until echo "----------------------------------" echo "请输入您的选择:&qu ...

  6. leetcode12_C++整数转罗马数字

    小弟不才,有错误或者更好解,求留言. 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如, ...

  7. arcgis10.2怎么把地理坐标系转化为投影坐标系(平面,米制坐标) arcmap 10.2 从 WGS_1984 转 Beijing_1954

    方法一:在Arcmap中转换:从 WGS_1984 转 Beijing_19541.加载要转换的数据,右下角为经纬度2.点击视图——数据框属性——坐标系统3.导入或选择正确的坐标系(如选:Beijin ...

  8. 重构:越来越长的 switch ... case 和 if ... else if ... else

    在代码中,时常有就一类型码(Type Code)而展开的如 switch ... case 或 if ... else if ... else 的条件表达式.随着项目业务逻辑的增加及代码经年累月的修改 ...

  9. python基础知识-01-编码输入输出变量

    python其他知识目录 名词解释: 编辑器 ide 程序员 操作系统 ASCAII码 unicode utf-8 浅谈CPU.内存.硬盘之间的关系 操作系统及Python解释器工作原理讲解 关于编译 ...

  10. 微信小程序-----自定义验证码实现

    这一段时间做小程序项目,使用的是mpvue的框架,需要自己实现验证码输入,模拟input的光标,上一个框输入后后一个框自动获取焦点,删除时从后往前依次删除.下图是整体效果: <template& ...