您的位置:首页 > 其它

UVALive 2426 Multiple Morse Matches(kmp+dp)

2015-07-17 18:53 369 查看

题意:

将下面给的字符串转成莫斯电码,问完全由下面的字符串转化而成的莫斯电码一共有多少种情况。

解释样例:第一种为ATTACK+DAWNATTACK+DAWN,第二种为AT+TACK+DAWNAT+TACK+DAWN。

思路:

先用KMP求出每个小的字符串匹配串的结束位置,然后转化为一个邻接表,求出该邻接表,从1开始到lenT结束共有几条路径。

这里可以用dp来求解,dp公式比较简单,想想就推出来了。

dp[edge[i][k]]+=dp[i]dp[edge[i][k]] += dp[i]

总结:

在写KMP循环求解结束位置的时候多写了一个条件,j<lenPj < lenP导致结果一直出不来,因为这样可能导致只算一次,而后面的模式串无法匹配到,下次一定要注意不要犯这样的错误了。

mymy codecode

[code]#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
#include <string>
#include <vector>
#include <cstdlib>
using namespace std;
typedef long long ll;
const int N = 1005;

string morse[] = {
    ".-", "-...", "-.-.", "-..",
    ".", "..-.", "--.", "....",
    "..", ".---", "-.-", ".-..",
    "--", "-.", "---", ".--.",
    "--.-", ".-.", "...", "-",
    "..-", "...-", ".--", "-..-",
    "-.--",  "--.."};

map<char, string> mp;
void getTable() {
    for(char ch = 'A'; ch <= 'Z'; ch++)
        mp[ch] = morse[ch-'A'];
}

vector<int> edge
;
string tar, pat;
int lenT, lenP;
ll dp
;

int jump
;
void getNext() {
    int j = 0, k = -1;
    jump[0] = -1;
    while(j < lenP) {
        if(k == -1 || pat[j] == pat[k])
            jump[++j] = ++k;
        else k = jump[k];
    }
}

void kmp() {
    lenT = tar.size(), lenP = pat.size();
    getNext();
    int j = 0, k = 0;
    while(j < lenT) {
        if(k == -1 || tar[j] == pat[k]) {
            j++, k++;
        }else k = jump[k];

        if(k == lenP) {
            edge[j - lenP].push_back(j);
        }
    }
}

string trans(string str) {
    string ret = "";
    for(int i = 0; i < str.size(); i++)
        ret += mp[str[i]];
    return ret;
}

void init() {
    memset(dp, 0, sizeof(dp));
    lenT = tar.size();
    for(int i = 0; i <= lenT; i++) {
        edge[i].clear();
    }
}

int main() {
    getTable(); 
    int T, n;
    scanf("%d", &T);
    while(T--) {
        init();
        cin >> tar;
        scanf("%d", &n);    

        string str;
        for(int i = 0; i < n; i++) {
            cin >> str;
            pat = trans(str);
            kmp();
        }

        dp[0] = 1;
        for(int i = 0; i < lenT; i++) {
            for(int k = 0; k < edge[i].size(); k++)
                dp[edge[i][k]] += dp[i];
        }

        printf("%lld\n", dp[lenT]);
        if(T) puts("");
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: