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

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 s1s2sN from left to right. (Here, s=s1+s2++sN holds.) Snuke wants to satisfy the following condition:

  • For each i (1iN), 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   
using namespace std;  
string s;  
unordered_mapcnt;  
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表示出现奇数次。这样就很容易维护答案了。 
*/




你可能感兴趣的:(atcoder,动态规划,状压dp,字符串,动态规划-状压dp)