uvalive 2965(状态压缩)
2015-02-12 17:57
387 查看
题意: 有n个字母组成的字符串,选尽量多的字符串,每个字母出现的都是偶数次。
题解:用状态压缩,把每个字符串出现的字母都在对应位置标记,如果出现偶数次标记为0,出现奇数次标记为1,那么最后选择的所有字符串对应位异或运算后应该是0,xor值是0的两个数要相等。然后因为每个字符串都是要或者不要,暴力要2^n,为了减少时间,用中途相遇法,先把前n / 2个字符串暴力一下,把对应子集内选中的字符串都xor一遍,更新相等xor的对应子集选中字符串数量(存到map里),然后枚举后n / 2个字符串的所有子集,在map中查找更新出最大子集。
#include <stdio.h>
#include <map>
using namespace std;
const int N = 30;
map<int, int> m;
char str[1000];
int f
;
int bitcount(int x) {
return x == 0 ? 0 : bitcount(x / 2) + (x & 1);
}
int main() {
int n;
while (scanf("%d", &n) == 1 && n) {
m.clear();
for (int i = 0; i < n; i++) {
scanf("%s", str);
f[i] = 0;
for (int j = 0; str[j] != '\0'; j++)
f[i] ^= (1 << str[j] - 'A');
}
int n1 = n / 2, n2 = n - n1;
for (int i = 0; i < (1 << n1); i++) {
int x = 0;
for (int j = 0; j < n1; j++)
if (i & (1 << j))
x ^= f[j];
if (!m.count(x) || bitcount(m[x]) < bitcount(i))
m[x] = i;
}
int res = 0;
for (int i = 0; i < (1 << n2); i++) {
int x = 0;
for (int j = 0; j < n2; j++)
if (i & (1 << j))
x ^= f[n1 + j];
if (m.count(x) && bitcount(res) < bitcount(m[x]) + bitcount(i))
res = (i << n1) ^ m[x];
}
printf("%d\n", bitcount(res));
for (int i = 0; i < n; i++)
if (res & (1 << i))
printf("%d ", i + 1);
printf("\n");
}
return 0;
}
题解:用状态压缩,把每个字符串出现的字母都在对应位置标记,如果出现偶数次标记为0,出现奇数次标记为1,那么最后选择的所有字符串对应位异或运算后应该是0,xor值是0的两个数要相等。然后因为每个字符串都是要或者不要,暴力要2^n,为了减少时间,用中途相遇法,先把前n / 2个字符串暴力一下,把对应子集内选中的字符串都xor一遍,更新相等xor的对应子集选中字符串数量(存到map里),然后枚举后n / 2个字符串的所有子集,在map中查找更新出最大子集。
#include <stdio.h>
#include <map>
using namespace std;
const int N = 30;
map<int, int> m;
char str[1000];
int f
;
int bitcount(int x) {
return x == 0 ? 0 : bitcount(x / 2) + (x & 1);
}
int main() {
int n;
while (scanf("%d", &n) == 1 && n) {
m.clear();
for (int i = 0; i < n; i++) {
scanf("%s", str);
f[i] = 0;
for (int j = 0; str[j] != '\0'; j++)
f[i] ^= (1 << str[j] - 'A');
}
int n1 = n / 2, n2 = n - n1;
for (int i = 0; i < (1 << n1); i++) {
int x = 0;
for (int j = 0; j < n1; j++)
if (i & (1 << j))
x ^= f[j];
if (!m.count(x) || bitcount(m[x]) < bitcount(i))
m[x] = i;
}
int res = 0;
for (int i = 0; i < (1 << n2); i++) {
int x = 0;
for (int j = 0; j < n2; j++)
if (i & (1 << j))
x ^= f[n1 + j];
if (m.count(x) && bitcount(res) < bitcount(m[x]) + bitcount(i))
res = (i << n1) ^ m[x];
}
printf("%d\n", bitcount(res));
for (int i = 0; i < n; i++)
if (res & (1 << i))
printf("%d ", i + 1);
printf("\n");
}
return 0;
}
相关文章推荐
- UVaLive 2965 Jurassic Remains (状态压缩)
- 例题1.25 侏罗纪 Jurassic Remains UVALive - 2965 状态压缩 + 中途相遇法
- uvalive2965(状态压缩)
- uvalive 7834 状态压缩dp
- 状态压缩 UVALive 6068 The Little Girl who Picks Mushrooms (12长春C)
- UVALive 6625_状态压缩
- UVALive 6625 Diagrams & Tableaux (状态压缩DP)
- UVALive - 4643 Twenty Questions (状态压缩)
- UVA - 1252 UVALive - 4643 状态压缩dp
- UVALive 2031 Dance Dance Revolution (舞步转移,状态压缩DP,4级)
- UVALive 3953 Strange Billboard (状态压缩+枚举)
- UVALive 2031 Dance Dance Revolution (舞步转移,状态压缩DP,4级)
- uvalive4794(集合+状态压缩)
- UVALive 3956 Key Task (bfs+状态压缩)
- UVALive - 3693 Balancing the Scale 枚举 + 状态压缩
- UVAlive 4999 状态压缩DP+最短路
- UVALive 6432 —— Influence(记忆化搜索 + 状态压缩)
- UVALive4794[Sharing Chocolate] 状态压缩动态规划
- UVA 11795 - Mega Man's Mission(状态压缩DP)
- UVA 11825 集合枚举 状态压缩 dp