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)
    {
        memsetnext[size], -1, sizeofnext[size]));
        Fail[size] = End[size] = false;

        return size++;
    }
    void InIt)
    {
        size = 0;
        root = newnode);
    }

    void Insertchar s[])
    {
        int now = root;

        forint i=0; s[i]; i++)
        {
            int k = strchrWordList, s[i]) - WordList;

            ifnext[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;

        forint i=0; i<MaxSon; i++)
        {
            ifnext[now][i] == -1)
                next[now][i] = root;
            else
            {
                Fail[next[now][i]] = root;
                Q.pushnext[now][i]);
            }
        }

        whileQ.size))
        {
            now = Q.front);
            Q.pop);

            forint i=0; i<MaxSon; i++)
            {
                ifnext[now][i] == -1)
                    next[now][i] = next[Fail[now]][i];
                else
                {
                    Fail[next[now][i]] = next[Fail[now]][i];
                    Q.pushnext[now][i]);
                }
            }

            End[now] |= End[Fail[now]];
        }
    }
    void GetMatrix)
    {
        memsetMatrix, false, sizeofMatrix));

        forint i=0; i<size; i++)
        forint k=0; k<MaxSon; k++)
        {
            if!End[next[i][k]] && !End[i])
                Matrix[i][next[i][k]] += 1;
        }
    }
};
Ac_Trie ac;

void BigNumAddint a[], int num, int b[])
{
    forint i=0; i<MAXN; i++)
        b[i] += a[i] * num;

    forint i=0; i<MAXN-1; i++)
    {
        b[i+1] += b[i] / 10;
        b[i] %= 10;
    }
}

int main)
{
    int N, P;

    whilescanf"%d%d%d", &MaxSon, &N, &P) != EOF)
    {
        char s[MAXN];
        ac.InIt);

        getchar);
        getsWordList);

        whileP--)
        {
            getss);
            ac.Inserts);
        }

        ac.GetFail);
        ac.GetMatrix);

        int dp[2][MAXN][MAXN] = {0}, op=0;
        dp[1][0][0] = 1;
        whileN--)
        {
            memsetdp[op], false, sizeofdp[op]));

            forint i=0; i<ac.size; i++)
            forint j=0; j<ac.size; j++)
            {
                ifMatrix[i][j])
                {///dp[op][j] += dp[op^1][i] * Matrix[i][j];
                    BigNumAdddp[op^1][i], Matrix[i][j], dp[op][j]);
                }
            }

            op ^= 1;
        }

        int ans[MAXN] = {0};

        forint i=0; i<ac.size; i++)
            BigNumAdddp[op^1][i], 1, ans);

        N = MAXN - 1;
        whileans[N] == 0 && N > 0)
            N--;

        forint i=N; i>=0; i--)
            printf"%d", ans[i]);
        printf"
");
    }

    return 0;
}

Published by

风君子

独自遨游何稽首 揭天掀地慰生平