您的位置:首页 > Web前端

【AtCoder CODE FESTIVAL 2017 qual C】D - Yet Another Palindrome Partitioning (状压dp 字符串)

2017-10-24 11:13 465 查看


D - Yet Another Palindrome Partitioning

Time limit : 3sec / Memory limit : 512MB

Score : 700 points

Problem Statement

We have a string s consisting
of lowercase English letters. Snuke is partitioning s into some number of non-empty substrings.
Let the subtrings obtained be s1, s2, …, sN from
left to right. (Here, s=s1+s2+…+sN holds.)
Snuke wants to satisfy the following condition:
For each i (1≤i≤N),
it is possible to permute the characters in si and
obtain a palindrome.
Find the minimum possible value of N when
the partition satisfies the condition.

Constraints

1≤|s|≤2×105
s consists of lowercase English letters.

Input

Input is given from Standard Input in the following format:
s


Output

Print the minimum possible value of N when
the partition satisfies the condition.

Sample Input 1

Copy
aabxyyzz


Sample Output 1

Copy
2

The solution is to partition s as 
aabxyyzz
 = 
aab
 + 
xyyzz
.
Here, 
aab
 can be permuted to form a palindrome 
aba
,
and 
xyyzz
 can be permuted to form a palindrome 
zyxyz
.

Sample Input 2

Copy
byebye


Sample Output 2

Copy
1

byebye
 can
be permuted to form a palindrome 
byeeyb
.

Sample Input 3

Copy
abcdefghijklmnopqrstuvwxyz


Sample Output 3

Copy
26


Sample Input 4

Copy
abcabcxabcx


Sample Output 4

Copy
3

The solution is to partition s as 
abcabcxabcx
 = 
a
 + 
b
 + 
cabcxabcx
.

#include <bits/stdc++.h>
using namespace std;
string s;
unordered_map<int, int>cnt;
int main(){
cin>>s;
int cur = 0, x;
cnt[cur] = 1;
for(int i = 0; i < s.size(); ++i){
cur ^= (1 << (s[i] - 'a'));
if(cur ==  0){
continue;
}
else{
x = 1e8;
if(cnt[cur] > 0){
x= min(x, cnt[cur]);
}
for(int j = 0; j < 26; ++j){
if((cur ^ (1 << j)) == 0){ x = 1; break;}
else{
if(cnt[cur ^ (1 << j)] > 0) x = min(x, cnt[cur ^ (1 << j)] + 1);
else{
x = min(x, cnt[cur ^ (1 << (s[i] - 'a'))] + 1);
}
}
}
cnt[cur] = x;
}
}
cout << cnt[cur] << endl;
}

/*
题意:
长度2e5的字符串,问最少需要分成多少个连续的子串,在子串内部的字符可以随意排列的情况下使得这些子串都是回文串。

思路:对于子串,只要出现奇数次的字符不超过1个,该子串就是回文串。一共26个小写字母,可以用一个整数状压记录,第i
位表示该字母出现多少次。某位为0表示出现偶数次,为1表示出现奇数次。这样就很容易维护答案了。
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息