hdu4057 Rescue the Rabbit,AC自动机,状态压缩dp
2014-10-15 22:41
375 查看
hdu4057 Rescue the Rabbit,AC自动机,状态压缩dp
题意:给n(<=10)个串,每个串有个权值,给一个长度(<=100),问这个长度能构造出的最大权值的串是多少。
一个串只能被计算一次权值。
将这些串建trie树,那么树节点不会超过1000个。
然后状态压缩dp,状态有2^10=1024种,节点数1000个,每次转移有四种,共有100次转移,转移用AC自动机优化就是O(1)。
因此复杂度就是O(1000*1024*100*4)。实际会更小一些,因为树节点没有那么多。每次可转移的也没有那么多。
dp[i][j][k]表示走i步,包含j中二进制位为1的串,当前状态是k是否可达。
i那一维可用滚动数组弄掉。
题意:给n(<=10)个串,每个串有个权值,给一个长度(<=100),问这个长度能构造出的最大权值的串是多少。
一个串只能被计算一次权值。
将这些串建trie树,那么树节点不会超过1000个。
然后状态压缩dp,状态有2^10=1024种,节点数1000个,每次转移有四种,共有100次转移,转移用AC自动机优化就是O(1)。
因此复杂度就是O(1000*1024*100*4)。实际会更小一些,因为树节点没有那么多。每次可转移的也没有那么多。
dp[i][j][k]表示走i步,包含j中二进制位为1的串,当前状态是k是否可达。
i那一维可用滚动数组弄掉。
#include<iostream> #include<cstring> #include<cstdio> using namespace std; #define NN 1040 int tottrie,q[NN],root; int ptr[500]; char s[NN]; struct trie{ int fail; int son[4]; int flag; void init(){ fail=0; flag=0; memset(son,0,sizeof(son)); } }tt[NN]; void init(){ ptr['A']=0;ptr['T']=1;ptr['C']=2;ptr['G']=3; tottrie=0; root=++tottrie; tt[1].init(); } void insert(char *a,int v){ int j=root; int i; while(*a){ i=ptr[*a]; if (!tt[j].son[i]) {tt[j].son[i]=++tottrie;tt[tottrie].init();} j=tt[j].son[i]; a++; } tt[j].flag=1<<v; } void build_ac(){ int i,j,u,v; int rear=0,front=0; q[++rear]=root; while(front<rear){ u=q[++front]; for(i=0;i<4;++i){ j=tt[u].fail; while(j&&!tt[j].son[i]) j=tt[j].fail; if (tt[u].son[i]){ v=tt[u].son[i]; if (!j) tt[v].fail=root; else{ tt[v].fail=tt[j].son[i]; tt[v].flag|=tt[tt[v].fail].flag; } q[++rear]=v; } else { if (!j) tt[u].son[i]=root; else tt[u].son[i]=tt[j].son[i]; } } } } int v[NN]; int dp[2][NN][NN]; const int inf =10000000; int main(){ //freopen("gin.txt","r",stdin); int i,j,l,o,pas,now,tn,n,k,ans,vv,tmp; while(scanf("%d%d",&n,&k)!=EOF){ init(); for(i=1;i<=n;++i){ scanf("%s%d",s,&v[i]); if (strlen(s)>k) continue; insert(s,i-1); } build_ac(); memset(dp,0,sizeof(dp)); pas=0;now=1; tn=1<<n; dp[1][0][1]=1; for(i=1;i<=k;++i){ pas=now;now=1-now; for(j=1;j<=tottrie;++j) for(l=0;l<tn;++l) {dp[now][l][j]=0;} for(j=1;j<=tottrie;++j){ for(l=0;l<tn;++l)if (dp[pas][l][j]){ for(o=0;o<4;++o){ vv=tt[j].son[o]; dp[now][l|tt[vv].flag][vv]=1; } } } } ans=-inf; for(i=1;i<=tottrie;++i){ for(j=0;j<tn;++j)if (dp[now][j][i]){ tmp=0; for(l=0;l<n;++l){ if (j&(1<<l)) tmp+=v[l+1]; } if (tmp>ans) ans=tmp; } } if (ans<0) printf("No Rabbit after 2012!\n"); else printf("%d\n",ans); } return 0; }
相关文章推荐
- HDU 4057 Rescue the Rabbit ( AC自动机 + 状态压缩DP )
- HDU 4057 Rescue the Rabbit(11年大连,AC自动机+状态压缩DP)
- HDU 4057 Rescue the Rabbit(AC自动机+状态压缩dp)
- HDOJ 4057 - Rescue the Rabbit 简单的AC自动机+状态压缩DP
- Hdu 4057 Rescue the Rabbit (AC自动机+状态压缩dp) - 2011 ACM-ICPC Dalian Regional Contest Problem G
- HDU4057 Rescue the Rabbit(AC自动机+状压DP)
- hdu4758 hdu2825 hdu4057 AC自动机与状态压缩dp的结合
- hdu4057(ac自动机,状态压缩dp)
- hdu4758 hdu2825 hdu4057 AC自动机与状态压缩dp的结合
- hdu4057 Rescue the Rabbit【AC自动机+dp滚动数组】
- hdu4057 Rescue the Rabbit(AC自动机+DP)
- poj 3311Hie with the Pie(解题的两种方法)状态压缩dp,或全排列。
- POJ 3666 Making the Grade 滚动数组+状态压缩DP
- 状态压缩DP-Hie With the Pie(POJ 3311)
- HDU 4758 Walk Through Squares( AC自动机 + 状态压缩DP )
- poj 3311 Hie with the Pie (floyd+状态压缩dp)
- POJ 3311 Hie with the Pie(DP状态压缩+最短路径)
- HDU 3247 AC自动机 + 状态压缩dp
- POJ3311——Hie with the Pie(状态压缩DP)
- POJ3311 Hie with the Pie(状态压缩dp)