zoukankan      html  css  js  c++  java
  • Censored!

    题目大意:首先给一个字符集合,这个集合有N个字符,然后需要一个长度为M的句子,但是据子里面不能包含的串有P个,每个串里面的字符都是有字符集和里面的字符构成的,现在想知道最多能构造多少个不重复的句子。
     
    分析:跟以前做过的那两题差不多,不过这个不让取余....不过考虑到字符长度也不大,最多也就50,所以使用一般的dp也可以。ps.在做高高精度运算的时候输出答案竟然正着输出了....然后就一直WA....确实有些时间没有敲过高精度题目了。
     
    代码如下:
    ==============================================================================================================================
    #include<iostream>
    #include<algorithm>
    #include<stdio.h>
    #include<string.h>
    #include<queue>
    using namespace std;
    
    const int MAXN = 107;
    const int oo = 1e9+7;
    
    char WordList[MAXN];
    int MaxSon, Matrix[MAXN][MAXN];
    
    struct Ac_Trie
    {
        int next[MAXN][MAXN], size;
        int Fail[MAXN], End[MAXN], root;
    
        int newnode()
        {
            memset(next[size], -1, sizeof(next[size]));
            Fail[size] = End[size] = false;
    
            return size++;
        }
        void InIt()
        {
            size = 0;
            root = newnode();
        }
    
        void Insert(char s[])
        {
            int now = root;
    
            for(int i=0; s[i]; i++)
            {
                int k = strchr(WordList, s[i]) - WordList;
    
                if(next[now][k] == -1)
                    next[now][k] = newnode();
                now = next[now][k];
            }
    
            End[now] = true;
        }
    
        void GetFail()
        {
            queue<int> Q;
            int now = root;
    
            Fail[root] = root;
    
            for(int i=0; i<MaxSon; i++)
            {
                if(next[now][i] == -1)
                    next[now][i] = root;
                else
                {
                    Fail[next[now][i]] = root;
                    Q.push(next[now][i]);
                }
            }
    
            while(Q.size())
            {
                now = Q.front();
                Q.pop();
    
                for(int i=0; i<MaxSon; 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]);
                    }
                }
    
                End[now] |= End[Fail[now]];
            }
        }
        void GetMatrix()
        {
            memset(Matrix, false, sizeof(Matrix));
    
            for(int i=0; i<size; i++)
            for(int k=0; k<MaxSon; k++)
            {
                if(!End[next[i][k]] && !End[i])
                    Matrix[i][next[i][k]] += 1;
            }
        }
    };
    Ac_Trie ac;
    
    void BigNumAdd(int a[], int num, int b[])
    {
        for(int i=0; i<MAXN; i++)
            b[i] += a[i] * num;
    
        for(int i=0; i<MAXN-1; i++)
        {
            b[i+1] += b[i] / 10;
            b[i] %= 10;
        }
    }
    
    int main()
    {
        int N, P;
    
        while(scanf("%d%d%d", &MaxSon, &N, &P) != EOF)
        {
            char s[MAXN];
            ac.InIt();
    
            getchar();
            gets(WordList);
    
            while(P--)
            {
                gets(s);
                ac.Insert(s);
            }
    
            ac.GetFail();
            ac.GetMatrix();
    
            int dp[2][MAXN][MAXN] = {0}, op=0;
            dp[1][0][0] = 1;
            while(N--)
            {
                memset(dp[op], false, sizeof(dp[op]));
    
                for(int i=0; i<ac.size; i++)
                for(int j=0; j<ac.size; j++)
                {
                    if(Matrix[i][j])
                    {///dp[op][j] += dp[op^1][i] * Matrix[i][j];
                        BigNumAdd(dp[op^1][i], Matrix[i][j], dp[op][j]);
                    }
                }
    
                op ^= 1;
            }
    
            int ans[MAXN] = {0};
    
            for(int i=0; i<ac.size; i++)
                BigNumAdd(dp[op^1][i], 1, ans);
    
            N = MAXN - 1;
            while(ans[N] == 0 && N > 0)
                N--;
    
            for(int i=N; i>=0; i--)
                printf("%d", ans[i]);
            printf("
    ");
        }
    
        return 0;
    }
  • 相关阅读:
    Servlet基础知识
    字节流
    MyEclipse快捷键
    Css Flex布局
    Django Session
    Django 分页
    Django Cookie
    Django 模板
    Python redis-py
    JQuery ajax
  • 原文地址:https://www.cnblogs.com/liuxin13/p/4755608.html
Copyright © 2011-2022 走看看