POJ - 1699 Best Sequence (AC自动机+状压DP)

题意:

给出n(n<=10)个串,每个串的长度小于等于20,计算覆盖所有串的最短串长度

分析:

对所有串建立fail树,那么可以发现其实是在fail树上计算一个覆盖所有节点的最短路,因为最多10个串,所以我么考虑状压DP

dp[i][j] 表示到了当前状态为 i 的节点且一共走了 j 状态的串(第 k 个串走完的话标记 j 的第k位是1)

那么也很容易得到状态转移方程,在树上bfs计算即可。

//#include

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include //accumulate

#define mm(a,b) memset(a,b,sizeof(a))
#define ACCELERATE (ios::sync_with_stdio(false),cin.tie(0))
#define pii pair
#define pdd pair
#define pll pair
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define rush() int T;scanf("%d",&T);while(T--)
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define pf(a) printf("%d\n",a)
#define pf2(a,b) printf("%d %d\n",a,b)
#define pf3(a,b,c) printf("%d %d %d\n",a,b,c)
#define debug(x) cout<<#x<<": "< q;
        q.push(root);
        while(!q.empty()){
            int p=q.front();q.pop();
            for(int i=0;i<4;i++){
                if(~next[p][i]){
                    if(p==root) fail[next[p][i]]=root;
                    else fail[next[p][i]]=next[fail[p]][i];
                    q.push(next[p][i]);
                    cnt[next[p][i]]|=cnt[fail[next[p][i]]];
                }else{
                    if(p==root) next[p][i]=root;
                    else next[p][i]=next[fail[p]][i];
                }
            }
        }
    }
    int solve(){
        mm(dp,inf);
        dp[0][0]=0;
        queue que;
        que.push(mp(0,0));
        while(!que.empty()){
            int p=que.front().fi;
            int v=que.front().se;
            que.pop();
            for(int k=0;k<4;k++){
                int pp=next[p][k];
                if(pp==-1) pp=0;
                int vv=(v|cnt[pp]);
                if(dp[pp][vv]>dp[p][v]+1){
                    dp[pp][vv]=dp[p][v]+1;
                    que.push(mp(pp,vv));
//                    cout<>T;
    while(T--){
        cin>>n;
        string s;
        ac.clear();
        rep(i,1,n){
            cin>>s;
            for(int j=0;j

 

你可能感兴趣的:(动态规划,字符串)