la 2965 Jurassic Remains (中途相遇法)

把串分成前后两半,前面的做暴力枚举,并把结果丢到集合里去,

后面的也暴力枚举,并且每次的结果去集合里看有无出现过相同的.

如果有那么异或后为0,就是符合题目要求的,选出包含字符串个数最多的!

这样一优化,前后两个2^12+2^12,瞬间时间复杂度开方了!

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <stack>
#include <cmath>
#include <queue>
#include <set>
#include <map>
typedef long long ll;
using namespace std;

const int inf=0x3f3f3f3f;
const int maxn=1e6+10;

int n;
int a[25];

map<int,int>table;

int bitcount(int x){
	return x==0 ? 0 : (bitcount(x/2)+(x&1)) ;
}

int main()
{
	while(scanf("%d",&n)!=EOF && n){
		char s[1005];
		for(int i=0;i<n;++i){
			scanf("%s",&s);
			//printf("%s\n", s);
			a[i]=0;
			for(int j=0 ; s[j]!=‘\0‘ ;++j ){
				a[i]^=( 1<<( s[j]-‘A‘ ) );
			}
		}

		int n1=n/2;
		int n2=n-n1;
		table.clear();
		for(int i=0;i< (1<<n1) ;++i ){
			int x=0;
			for(int j=0;j<n1;++j){
				if(i & (1<<j)){
					x^=a[j];
				}
			}
			if(!table.count(x) || bitcount(table[x])<bitcount(i))table[x]=i;
		}
		int ans=0;
		for(int i=0;i< (1<<n2) ;++i){
			int x=0;
			for(int j=0;j<n2;++j){
				if(i& (1<<j) ){
					x^=a[n1+j];
				}
			}
			if( table.count(x) && bitcount(ans)< bitcount(table[x])+bitcount(i) ){
				ans=(i<<n1)^table[x];
			}
		}

		printf("%d\n",bitcount(ans) );
		for(int i=0;i<n;++i)
			if( ans&(1<<i) )
				printf("%d ",i+1 );
		printf("\n");
	}
	return 0;
}

  

时间: 2024-08-05 22:15:55

la 2965 Jurassic Remains (中途相遇法)的相关文章

UVA 1326 Jurassic Remains 中途相遇法

题目链接:点击打开链接 题意:给定n个字符串,选尽可能多的字符串使得每种字母出现的次数为偶数次 思路: 中途相遇法 import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.LinkedLi

LA 2965 Jurassic Remains

这是我做的第一道状态压缩的题目,而且我自己居然看懂了,理解得还算透彻. 题意:给出若干个大写字母组成的字符串,然后选取尽量多的字符串使得这些字母出现偶数次. 最朴素的想法,穷举法:每个字符串只有选和不选两种情况,那么穷举的时间复杂度是O(2n) 优化:将这n个字符串分成两半,先后枚举前n1个字符串所有可能的情况,计算xor值并保存在table中 再枚举后半部分的xor值并在table中查找(因为如果两者的异或值相同,则进行异或运算后的值为0),如果找到,将ans更新为bitcount较大的那种方

UVALive - 2965 Jurassic Remains

Jurassic Remains Time Limit: 18000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu [Submit]   [Go Back]   [Status] Description Paleontologists in Siberia have recently found a number of fragments of Jurassic period dinosaur skeleton. The pal

uva 6757 Cup of Cowards(中途相遇法,貌似)

uva 6757 Cup of CowardsCup of Cowards (CoC) is a role playing game that has 5 di?erent characters (Mage, Tank, Fighter,Assassin and Marksman). A team consists of 5 players (one from each kind) and the goal is to kill amonster with L life points. The

uva1152 - 4 Values whose Sum is 0(枚举,中途相遇法)

用中途相遇法的思想来解题.分别枚举两边,和直接暴力枚举四个数组比可以降低时间复杂度.可是我不会写...看了紫书作者刘汝佳老师的代码,真是太美了!简单明了,就像看吕钦下的棋一样.我就模仿的写了一下: #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<map> #include<set>

POJ 1840 Eqs Hash + 中途相遇法

把等式分成两拨算用中途相遇法就好了. 不过要注意的是这里不能用map,会超时,要自己手写hash,我重载了[]操作符之后用起来和map差不多,很随意 #include <cstdio> #include <cstring> #include <iostream> #include <map> #include <set> #include <vector> #include <string> #include <qu

Codeforces Round #297 (Div. 2) E题. Anya and Cubes (中途相遇法)

题目地址:Anya and Cubes 比赛的时候居然没想起中途相遇法...这题也是属于想起来就很简单系列. 中途相遇法也叫折半搜索.就是处理前一半,把结果储存起来,再处理后一半,然后匹配前一半存储的结果. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib

HDU 5936 Difference 【中途相遇法】(2016年中国大学生程序设计竞赛(杭州))

Difference Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 62    Accepted Submission(s): 19 Problem Description Little Ruins is playing a number game, first he chooses two positive integers y an

【中途相遇法】【STL】BAPC2014 K Key to Knowledge

题目链接: http://codeforces.com/gym/100526 http://acm.hunnu.edu.cn/online/?action=problem&type=show&id=11674&courseid=0 题目大意: N个学生M道题(1<=N<=12,1<=M<=30),每道题只有正误两种选项(0 1),每个学生的答题情况和正确题数已知,求标准答案可能有多少种. 如果标准答案只有一种则输出标准答案,否则输出解的个数. 题目思路: [