程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> HDU - 2825 Wireless Password(AC自動機+DP)

HDU - 2825 Wireless Password(AC自動機+DP)

編輯:C++入門知識

HDU - 2825 Wireless Password(AC自動機+DP)


Description

Liyuan lives in a old apartment. One day, he suddenly found that there was a wireless network in the building. Liyuan did not know the password of the network, but he got some important information from his neighbor. He knew the password consists only of lowercase letters 'a'-'z', and he knew the length of the password. Furthermore, he got a magic word set, and his neighbor told him that the password included at least k words of the magic word set (the k words in the password possibly overlapping).

For instance, say that you know that the password is 3 characters long, and the magic word set includes 'she' and 'he'. Then the possible password is only 'she'.

Liyuan wants to know whether the information is enough to reduce the number of possible passwords. To answer this, please help him write a program that determines the number of possible passwords.

Input

There will be several data sets. Each data set will begin with a line with three integers n m k. n is the length of the password (1<=n<=25), m is the number of the words in the magic word set(0<=m<=10), and the number k denotes that the password included at least k words of the magic set. This is followed by m lines, each containing a word of the magic set, each word consists of between 1 and 10 lowercase letters 'a'-'z'. End of input will be marked by a line with n=0 m=0 k=0, which should not be processed.

Output

For each test case, please output the number of possible passwords MOD 20090717.

Sample Input

 10 2 2
hello 
world 
4 1 1
icpc 
10 0 0
0 0 0 

Sample Output

 2
1
14195065 

題意:讓你構造一個長度為n的字符串,使得至少包含共m個的集合裡的k個,求個數。
思路:AC自動機構造,需要用到DP的思想,設dp[i][j][k]表示長度為i到達自動機狀態為j的時候且狀態k時的個數。我們需要用一個來表示狀態j包含的字符串的個數,也就是走到字符串末尾的個數,二進制表示。然後還要注意一點的是:我們在構造自動機的時候有fail指針的轉移,所以狀態j也需要結合它失配時候的狀態。

#include 
#include 
#include 
#include 
#include 
using namespace std;
const int mod = 20090717;

int n, m, k;
int dp[30][250][1<<10];
int num[5000];

struct Trie {
    int nxt[110][26], fail[110], end[110];
    int root, sz;

    int newNode() {
        for (int i = 0; i < 26; i++)
            nxt[sz][i] = -1;
        end[sz++] = 0;
        return sz - 1;
    }

    void init() {
        sz = 0;
        root = newNode();
    }

    void insert(char buf[], int id) {
        int now = root;
        for (int i = 0; buf[i]; i++) {
            if (nxt[now][buf[i]-'a'] == -1)
                nxt[now][buf[i]-'a'] = newNode();
            now = nxt[now][buf[i]-'a'];
        } 
        end[now] |= (1< q;
        fail[root] = root;
        for (int i = 0; i < 26; i++) {
            if (nxt[root][i] == -1) 
                nxt[root][i] = root;
            else {
                fail[nxt[root][i]] = root;
                q.push(nxt[root][i]);
            }
        }

        while (!q.empty()) {
            int now = q.front();
            q.pop();
            end[now] |= end[fail[now]];
            for (int i = 0; i < 26; i++) {
                if (nxt[now][i] == -1)
                    nxt[now][i] = nxt[fail[now]][i];
                else {
                    fail[nxt[now][i]] = nxt[fail[now]][i];
                    q.push(nxt[now][i]);
                }
            }
        }
    }

    int solve() {
        for (int i = 0; i <= n; i++)
            for (int j = 0; j < sz; j++)
                for (int k = 0; k < (1< 0) {
                        for (int x = 0; x < 26; x++) {
                            int ni = i+1;
                            int nj = nxt[j][x];
                            int nk = k | end[nj];
                            dp[ni][nj][nk] += dp[i][j][k];
                            dp[ni][nj][nk] %= mod;
                        }
                    }
        int ans = 0;
        for (int p = 0; p < (1<


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved