UVA 1326 Jurassic Remains

来源:互联网 发布:tower软件下载 编辑:程序博客网 时间:2024/05/15 23:52

题目链接:

 白书中高效算法设计中的例题,是个很好的题,学到了“中途相遇法”,太有用了,39ms就过了,直接枚举18s都TLE。

核心是将一个问题如果分成两个子问题,并且从子问题可以算出整体解,那么可以先将左半解暂存起来,再枚举右半部分,直接在左半解中查找对应的另一半.

代码:

#include <iostream>#include <cstdio>#include <cstring>#include <map>#include <algorithm>using namespace std;const int maxn=24;map<int ,int>table;char str[1000];int bitcount(int x){    int ans=0;    while(x) ans+=x&1 , x>>=1;    return ans;}int main(){     int N;    while(scanf("%d",&N)!=EOF && N){        table.clear();        int A[maxn]={0};        for(int i=0;i<N;i++){            scanf("%s",str);            for(int j=0;str[j]!='\0';j++){                A[i] ^= (1<<(str[j]-'A'));            }        }        int n1=N/2 , n2=N-n1;        for(int s=0 ;s<(1<<(n1)) ; s++){            int x=0;            for(int i=0;i<n1;i++)                if(s&(1<<i)) x^=A[i];            if(!table.count(x) || bitcount(table[x])<bitcount(s) ) table[x] = s;        }        int ans=0;        for(int s=0 ;s<(1<<n2) ; s++){            int x=0;            for(int i=0;i<n2;i++)                if(s&(1<<i)) x ^= A[i+n1];            if(table.count(x) && bitcount(ans) < bitcount(table[x]) + bitcount(s) )                ans = (s<<n1)|table[x];        }        printf("%d\n",bitcount(ans));        int first=1;        for(int i=0;i<N;i++){            if(ans&(1<<i)){                if(!first) printf(" "); first=0;                printf("%d",i+1);            }        }        printf("\n");    }    return 0;}