当前位置: 代码迷 >> 综合 >> 【折半搜索】AtCoder Grand Contest 026 String Coloring
  详细解决方案

【折半搜索】AtCoder Grand Contest 026 String Coloring

热度:43   发布时间:2023-09-27 07:17:33.0

题意:

给出一个字符串s。
给这个串的每个位置染上红/蓝色,要求正向读每个染成红色的字符所组成的字符串s1,与反向读每个染成蓝色的字符所组成的字符串s2,满足s1=s2


分析:

由于N很小,我们可以考虑折半搜索。先搜前一半,用字符串hash把蓝、红两种颜色的字符串表示出来,存入一个map里面,再搜后一半,还是用字符串hash求出方案数。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<map>
#define SF scanf
#define PF printf
#define MAXN 350
using namespace std;
typedef unsigned long long ll;
int n;
char s[MAXN];
map<pair<ll,ll> ,ll> used[MAXN][MAXN];
ll ans;
void dfs1(int x,ll sum1,ll sum2,int len1,int len2){if(x==n){used[len1][len2][make_pair(sum1,sum2)]++;return ;}dfs1(x+1,sum1*131+(ll)(s[x]-'a'+1),sum2,len1+1,len2);dfs1(x+1,sum1,sum2*131+(ll)(s[x]-'a'+1),len1,len2+1);
}
void dfs2(int x,ll sum1,ll sum2,int len1,int len2){if(x==n-1){ans+=used[len1][len2][make_pair(sum1,sum2)];return ;}dfs2(x-1,sum1*131+(ll)(s[x]-'a'+1),sum2,len1+1,len2);dfs2(x-1,sum1,sum2*131+(ll)(s[x]-'a'+1),len1,len2+1);
}
int main(){SF("%d",&n); SF("%s",s);dfs1(0,0,0,0,0); dfs2(2*n-1,0,0,0,0);PF("%llu",ans);
} 
  相关解决方案