Given n strings consisting of only uppercase letters, select as many strings as possible so that each letter in these strings is an even number. N <= 24
Idea: directly enumerate the selected or unselected strings. The complexity is O (2 ^ n ). In fact, there are simpler methods.
It is not important to specify the number of occurrences of each letter. It is important to specify an odd or even number of times. We use 0 to indicate an odd number and 1 to indicate an even number. For each string, we can calculate the corresponding binary number as follows. If expression A appears for an odd number of times, the first position of the binary number is 1 and the even number is 0. If expression B appears for an odd number, the second position of the binary number is 1 and the even number is 0 ...... Similarly, each location has a corresponding 0 or 1. In this way, a binary number is formed. So we can convert the question into finding as many numbers as possible, so that their difference or sum is 0.
The complexity of direct enumeration is O (2 ^ n), but we may choose not to select the n/2 digits before enumeration, store all possible exclusive OR values in an STL map (the key is an exclusive or sum, and the value is a set of optional or unselected States for this exclusive or sum, for the same key, retain the most selected number), and then select or not to select n/2 numbers after enumeration, calculate each exclusive or sum, check whether there are exclusive or equal keys in map (because two identical numbers have exclusive or 0 values), and update the answer.
This complexity is only O (2 ^ [n/2] * logn ).
# Include <cstdio> # include <map> # define MAXN 30 using namespace std; int n, a [MAXN]; char s [1005]; map <int, int> F; int bitcount (int x) {return x? Bitcount (x/2) + (x & 1): 0 ;}// calculate the number of 1 contained in the binary representation of a number. int main () {while (~ Scanf ("% d", & n) {for (int I = 0; I <n; ++ I) {scanf ("% s", s ); a [I] = 0; for (int j = 0; s [j]; ++ j) a [I] ^ = (1 <(s [j]-'A'); // converts A string to a number} F. clear (); // remember to clear int ing int n1 = n/2, n2 = n-n1; for (int I = 0; I <(1 <n1 ); + + I) // each status of n/2 before enumeration {int x = 0; for (int j = 0; j <n1; ++ j) x ^ = (I> j) & 1) * a [j]; // calculate the variance or and if (F. count (x) | bitcount (I)> bitcount (F [x]) F [x] = I; // F records the selection status of each string corresponding to an exclusive or value} int ans = 0; // The final selection status of the answer record for (int I = 0; I <(1 <n2); ++ I) // each status of n/2 after enumeration {int x = 0; for (int j = 0; j <n2; ++ j) x ^ = (I> j) & 1) * a [j + n1]; // calculate the exclusive or and if (F. count (x) & bitcount (I) + bitcount (F [x])> bitcount (ans) ans = (I <n1) | F [x]; // If an exclusive or the same exclusive or sum as the number of the first n/2 is found, update the answer} printf ("% d \ n", bitcount (ans )); for (int I = 0; I <n; ++ I) if (ans> I) & 1) printf ("% d", I + 1 ); printf ("\ n");} return 0 ;}