【折半枚举】 String Coloring

Problem Statement

You are given a string SS of length 2N2N consisting of lowercase English letters.

There are 22N22N ways to color each character in SS red or blue. Among these ways, how many satisfy the following condition?

  • The string obtained by reading the characters painted red from left to right is equal to the string obtained by reading the characters painted blue from right to left.

Constraints

  • 1N181≤N≤18
  • The length of SS is 2N2N.
  • SS consists of lowercase English letters.

Input

Input is given from Standard Input in the following format:

NN
SS

Output

Print the number of ways to paint the string that satisfy the condition.


Sample Input 1 Copy

Copy
4
cabaacba

Sample Output 1 Copy

Copy
4

There are four ways to paint the string, as follows:

  • cabaacba
  • cabaacba
  • cabaacba
  • cabaacba

Sample Input 2 Copy

Copy
11
mippiisssisssiipsspiim

Sample Output 2 Copy

Copy
504

Sample Input 3 Copy

Copy
4
abcdefgh

Sample Output 3 Copy

Copy
0

Sample Input 4 Copy

Copy
18
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

Sample Output 4 Copy

Copy
9075135300

The answer may not be representable as a 3232-bit integer.

代码如下:

 1 #include <iostream>
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4 bool vis[50];
 5 int n,m;
 6 string s;
 7 pair<string ,string > ps[1<<18];
 8 map<pair<string,string >,int > mp;
 9 typedef long long ll;
10 ll cnt=0;
11 void solve()
12 {
13     for(register int i=0;i< 1<<n;i++)
14     {
15         string t,tt;
16         for(register int j=0;j<n;j++)
17         {
18             if(i>>j&1)
19             {
20                 t+=s[j];
21                 //vis[j]=1;
22             }
23             else
24                 tt+=s[j];
25         }
26         ps[i]=make_pair(t,tt);
27         mp[ps[i]]++;
28     }
29     for(register int i=0;i<1<<n;i++)
30     {
31         string t,tt;
32         for(register int j=0;j<n;j++)
33         {
34             if(i>>j&1)
35             {
36                 t+=s[n+j];
37             }
38             else
39                 tt+=s[n+j];
40         }
41         reverse(t.begin(),t.end());
42         reverse(tt.begin(),tt.end());
43         cnt+=mp[make_pair(t,tt)];
44     }
45 }
46 inline int read()                                //读入优化
47 {
48     int x=0,f=1;
49     char c=getchar();
50     while (!isdigit(c))
51         f=c=='-'?-1:1,c=getchar();
52     while (isdigit(c))
53         x=(x<<1)+(x<<3)+(c^48),c=getchar();
54     return x*f;
55 }
56 int main()
57 {
58     n=read();
59     cin>>s;
60     solve();
61     cout << cnt << endl;
62     //cout << "Hello world!" << endl;
63     return 0;
64 }
65 /*
66 4
67 cabaacba
68 */
View Code

 

posted @ 2019-02-14 10:31  听风不成泣  阅读(198)  评论(0编辑  收藏  举报