码迷,mamicode.com
首页 > 其他好文 > 详细

poj3341

时间:2015-04-06 12:47:18      阅读:181      评论:0      收藏:0      [点我收藏+]

标签:

ac自动机加状压dp加广搜优化

技术分享
#include<iostream>
#include<map>
#include<string.h>
#include<stdio.h>
#include<algorithm>
#include<queue>
using namespace std;
const int maxa = 500;
const int cha = 4;
int n, m, k;
int num_[4];
map<char, int> mp;
/*struct point{
    short a[4];
    bool operator <(const point& b)const{
        if(a[0] != b.a[0]) return a[0] < b.a[0];
        else if(a[1] != b.a[1]) return a[1] < b.a[1];
        else if(a[2] != b.a[2]) return a[2] < b.a[2];
        else return a[3] < b.a[3];
    }
};
map<point, int>dp[maxa];
map<point, bool> bo;*/
int dp[500][11*11*11*11];
int num[maxa];
struct Tire{
    int next[maxa][cha], fail[maxa];
    long long end[maxa], po[maxa];
    int root, L;
    int newnode(){
        for(int i = 0; i < cha; i++){
            next[L][i] = -1;
        }
        end[L] = 0;
        num[L++] = 0;
        return L-1;
    }
    void init(){
        L = 0;
        root = newnode();
    }
    void insert(char buf[], int ii){
        int len = strlen(buf);
        int now = root;
        for(int i = 0; i < len; i++){
            int x = mp[buf[i]];
            if(next[now][x] == -1)
                next[now][x] = newnode();
            now = next[now][x];
            //printf("%d ", now);
        }//puts("");
        long long one = 1;
        end[now] |= (one<<ii);
    }
    void build(){
        queue<int>Q;
        fail[root] = root;
        for(int i = 0; i < cha; i++){
            if(next[root][i] == -1)
                next[root][i] = root;
            else{
                fail[next[root][i]] = root;
                Q.push(next[root][i]);
            }
        }
        while(!Q.empty()){//printf("*");
            int now = Q.front();
            end[now] |= end[fail[now]];
            long long p = end[now];
            while(p){
                num[now] += p%2;
                p /= 2;
            }
            Q.pop();
           // end[now] |= end[fail[now]];
            for(int i = 0; i < cha; i++){
                if(next[now][i] == -1)
                    next[now][i] = next[fail[now]][i];
                else{
                    fail[next[now][i]] = next[fail[now]][i];
                    Q.push(next[now][i]);
                   // printf("**%d %d\n",next[now][i],next[fail[    now]][i]);
                }
            }
        }
    }
    int solve(){//printf("**%d\n", next[1][3]);
        memset(dp, -1, sizeof(dp));
        dp[0][0] = 0;
        bool vis[11*11*11*11];
        memset(vis, 0, sizeof(vis));
        queue<int>que;
        que.push(0);
        while(!que.empty()){
            int now = que.front(); que.pop();
            //printf("%d ", now);
            int wei = 1;
            for(int i =0;i < 4; i++){/*if(now==1){printf("&&\n");
                    printf("%d %d\n", wei, num_[i]);
                }*/
                if(now % (wei*(num_[i]+1)) /wei == num_[i]){
                    wei *= num_[i] +1;
                    continue;
                }
                int Next_state = now+wei;
                if(!vis[Next_state]){
                    vis[Next_state] = 1;
                    que.push(Next_state);
                }
                for(int k = 0; k < L; k++){
                    /*if(k == 1 && now == 1){
                        printf("--%d %d\n", next[k][i],Next_state);
                    }*/
                    if(dp[k][now] == -1)continue;
                    dp[next[k][i]][Next_state] = max(dp[next[k][i]][Next_state], dp[k][now]+num[next[k][i]]);
                }
                wei *= (num_[i]+1);
            }
        }
        int ans = 0;
        int maxn = 1;
        for(int i = 0;i < 4; i++){
            maxn *= num_[i]+1;
        }
            for(int k = 0; k < maxn; k++){
        for(int i = 0; i < L; i++){//printf("%d %d %d\n", i, k, dp[i][k]);
                ans = max(ans, dp[i][k]);
            }
        }return ans;
    }
};
char buf[45];
Tire ac;
int main(){
    //freopen("in.cpp","r", stdin);
    mp[A] = 0;
    mp[T] = 1;
    mp[G] = 2;
    mp[C] = 3;
    int n;
    int Case = 1;
    while(scanf("%d", &n), n != 0){
        memset(num_, 0, sizeof(num_));
        ac.init();
        for(int i = 0; i < n; i++){
            scanf("%s", buf);
            ac.insert(buf, i);
        }
        scanf("%s", buf);
        memset(num, 0, sizeof(num));
        for(int i = 0; buf[i]; i++){
            num_[mp[buf[i]]] ++;
        }
        ac.build();
        printf("Case %d: %d\n", Case ++, ac.solve());
    }
}
/*
abcdefg
bcdefg
cdef
de
e
ssaabcdefg


*/
View Code

 

poj3341

标签:

原文地址:http://www.cnblogs.com/icodefive/p/4395710.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!