您的位置:首页 > 产品设计 > UI/UE

hdu 4057 Rescue the Rabbit

2013-06-26 22:54 330 查看
ac自动机的状压dp

dp[i][j][k]表示长度为i,包含字符串的状态为j,自动机的状态为k是否可行。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int root=0,N=4;
int n,m;
bool dp[2][1111][1111];
int c[1111][10],a[111];
int lon;
struct
{
int next[5],tmp,fail;
}trie[1111];

void trieini()
{
memset(trie,0,sizeof(trie));
lon=0;
}

void insert(char s[],int h)
{
int t=root;
int n=strlen(s+1);
for(int i=1;i<=n;i++)
{
if(trie[t].next[s[i]-'A']==0)
trie[t].next[s[i]-'A']=++lon;
t=trie[t].next[s[i]-'A'];
if(i==n)
trie[t].tmp=1<<h-1;
}
}

void getfail()
{
queue <int> q;
q.push(root);
while(!q.empty())
{
int t=q.front();
q.pop();
for(int i=0;i<N;i++)
if(trie[t].next[i])
{
int u=trie[t].next[i];
int tmp=trie[t].fail;
while(tmp!=root&&trie[tmp].next[i]==0)
tmp=trie[tmp].fail;
trie[u].fail=trie[tmp].next[i];
if(t==root) trie[u].fail=root;
trie[u].tmp|=trie[trie[u].fail].tmp;
q.push(u);
}
}
}

void work(char s[])
{
int n=strlen(s+1);
for(int i=1;i<=n;i++)
{
if(s[i]=='T')
s[i]='B';
else if(s[i]=='G')
s[i]='D';
}
}

void find()
{
for(int i=0;i<=lon;i++)
for(int p=0;p<4;p++)
{
int t=i;
while(t&&trie[t].next[p]==0)
t=trie[t].fail;
c[i][p]=trie[t].next[p];
}
}

int main()
{
while(scanf("%d %d",&n,&m)!=EOF)
{
trieini();
char s[111];
for(int i=1;i<=n;i++)
{
scanf("%s",s+1);
scanf("%d",&a[i]);
work(s);
insert(s,i);
}
getfail();
find();
memset(dp,0,sizeof(dp));
dp[0][0][0]=1;
for(int k=0;k<m;k++)
{
int now=k%2,to=(k+1)%2;
for(int i=0;i<(1<<n);i++)
for(int j=0;j<=lon;j++)
dp[to][i][j]=0;

for(int i=0;i<(1<<n);i++)
for(int j=0;j<=lon;j++)
if(dp[now][i][j])
for(int p=0;p<4;p++)
{
int u=c[j][p];
int v=trie[u].tmp;
dp[to][i|v][u]=1;
}
}
int to=m%2;
int ans=-1;
for(int i=0;i<(1<<n);i++)
for(int j=0;j<=lon;j++)
if(dp[to][i][j])
{
int sum=0;
for(int k=1;k<=n;k++)
{
int tmp=1<<k-1;
if(tmp&i)
sum+=a[k];
}
ans=max(ans,sum);
}
if(ans>=0)
printf("%d\n",ans);
else
printf("No Rabbit after 2012!\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: