luogu_P1026 统计单词个数

先区间DP处理区间单词个数,在线性DP一次求出答案,注意词典里可能有重复单词

#include<iostream>
#include<cstdio>

#define ri register int
#define u unsigned long long

namespace opt {

    inline u in() {
        u x(0),f(1);
        char s(getchar());
        while(s<'0'||s>'9') {
            if(s=='-') f=-1;
            s=getchar();
        }
        while(s>='0'&&s<='9') {
            x=(x<<1)+(x<<3)+s-'0';
            s=getchar();
        }
        return x*f;
    }

}

using opt::in;

#define NN 205

#include<cstring>
#include<algorithm>

namespace mainstay {
    
    u N,K,M,pow[NN]={(u)1},sum[NN];
    
    char s[NN];
    
    int f[NN][NN],g[NN][NN];
    
    const u bas=131;
    
    struct node{
        u len,hash;
    }a[NN];
    
    inline bool cmp(const node &x,const node &y){
        return x.hash<y.hash;
    }
    
    inline void solve() {
        N=in()*20,K=in();
        for(ri i(1);i<=N;++i) pow[i]=pow[i-1]*bas;
        for(ri i(1);i<=N;++i){
            char _s(getchar());
            while(_s<'a'||_s>'z') _s=getchar();
            sum[i]=sum[i-1]*bas+_s-'a'+1;
        }
        M=in();
        for(ri i(1);i<=M;++i){
            scanf("%s",s+1);
            a[i].len=std::strlen(s+1);
            for(ri j(1);j<=a[i].len;++j) a[i].hash=a[i].hash*bas+s[j]-'a'+1;
        }
        std::sort(a+1,a+M+1,cmp);
        for(ri len(1);len<=N;++len){
            for(ri i(1),j(i+len-1);j<=N;++i,++j){
                g[i][j]=g[i+1][j];
                u pre(0);
                for(ri k(1);k<=M;++k){
                    if(pre==a[k].hash) continue;
                    if(a[k].len<=len&&a[k].hash==sum[i+a[k].len-1]-pow[a[k].len]*sum[i-1]) ++g[i][j];
                    pre=a[k].hash;
                }
            }
        }
        std::memset(f,-0x3f,sizeof(f));
        f[0][0]=0;
        for(ri i(1);i<=N;++i){
            for(ri j(1);j<=K;++j){
                for(ri k(0);k<=i-1;++k){
                    f[i][j]=std::max(f[i][j],f[k][j-1]+g[k+1][i]);
                }
            }
        }
        std::cout<<f[N][K];
    }

}

int main() {

    //freopen("x.txt","r",stdin);
    mainstay::solve();

}

 

posted @ 2019-11-13 20:51  pai_hoo  阅读(125)  评论(0编辑  收藏  举报