UVALive 2965-Jurassic Remains (Mitm)中途相遇法+bitmask

http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34853


题目大意:给出N个字符串,字符串里面的字符全是大写字母,要求你在N个字符串中选出M个字符串,使这M个字符串的每个字符出现的个数为偶数,求M的最大值



把字符串压缩到一个int的26位。要求一个字符串子集中 所有字符出现个数为偶数,也就是所以字符串的异或值为0


n=24,直接枚举子集的2^N 略大。。


我们可以先枚举n/2个字符串的子集,并把值映射到map/hash,

然后再枚举后n-n/2个字符串的子集,枚举过程中,对一个值X,如果能在map里找到则更新答案,否则跳过

复杂度就从2^n降到了 2^(n/2)* logn  。。。(logn是map的)


#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;

const double pi=acos(-1.0);
double eps=0.000001; /*
					 __int64 min(__int64 a,__int64 b)
					 {return a<b?a:b;} 
					 __int64 max(__int64 a,__int64 b)
{return a>b?a:b;}*/

char tm[28][28];
int A[28];
int B[28];
int bit[28];
map<int,int>sb,ans;  
int main()
{
	int n;
	int i,j;
	for (i=0;i<26;i++)
		bit[i]=1<<i;
	
	
	while(scanf("%d",&n)!=EOF)
	{
		sb.clear();
		ans.clear();
		for (i=0;i<n;i++)
		{
			A[i]=0;
			scanf("%s",tm[i]);
			int len =strlen(tm[i]);
			for (j=0;j<len;j++)
				A[i]^=bit[ tm[i][j]-'A' ];
		}
		int n1=n/2;
		int n2=n-n1; 
		
		
		int all=1<<n1;
		sb[0]=0;
		ans[0]=0;
		for (i=0;i<all;i++)
		{
			int cun=0,tmp=0;
			int x=i;
			for (j=0;j<n1;j++)
			{
				if ((x&(1<<j))==0)continue;
				cun++;
				tmp^=A[j];
			}
			if (sb.count(tmp)==0||sb[tmp]<cun) 
				sb[tmp]=cun,ans[tmp]=i;
		}
		
		int maxx=0; 
		int max_mark1=0;
		int max_mark2=0;
		all=1<<n2;
		for (i=0;i<all;i++)
		{
			int cun=0,tmp=0;
			int x=i;
			for (j=0;j<n2;j++)
			{
				if ((x&(1<<j))==0)continue;
				cun++;
				tmp^=A[n1+j];
			}
			if (sb.count(tmp)==0) continue;
			if (cun+sb[tmp]>maxx)
			{
				max_mark1=ans[tmp];
				max_mark2=i;
				maxx=cun+sb[tmp];
			} 
		} 
		printf("%d\n",maxx);
		int out[80];
		int ok=0;
		
		for (i=0;i<n1;i++)
		{
			if (max_mark1&(1<<i)) out[++ok]=i;
		}
		for (i=0;i<n2;i++)
		{
			if (max_mark2&(1<<i)) out[++ok]=n1+i;
		}
		for (i=1;i<=ok;i++)
		{
			if (i!=1) printf(" ");
			printf("%d",out[i]+1);
		}
		printf("\n");
	}
	return 0;
	
}


你可能感兴趣的:(UVALive 2965-Jurassic Remains (Mitm)中途相遇法+bitmask)