zoukankan      html  css  js  c++  java
  • LA 3942 Remember the Word

    (Remember the Word ,LA 3942) 

    题目来源:https://vjudge.net/problem/UVALive-3942

    题意:给定一个字符串S以及n个单词,字符用这n个单词进行拆分,输出拆分的方案数。

    思路:dp+字典树

    可以先将这n个单词存储于字典树中,并记dp[i]:字符i开始的字符串的分解方案数量(即后缀S[i...end]),则动态转移方程为dp[i]=sum{dp[i+len(x)] | 单词x是S[i...end]的前缀}.

    找S[i...end]的前缀可以在字典树中查找。

    AC代码:

    #define _CRT_SECURE_NO_DEPRECATE
    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #include<string>
    #include<iomanip>
    #include<map>
    #include<stack>
    #include<set>
    #include<queue>
    #include<cstdio>
    using namespace std;
    #define N_MAX 4000+5
    #define L_MAX 4000*100+5
    #define INF 0x3f3f3f3f
    #define MOD 20071027
    typedef long long ll;
    int n;
    int dp[L_MAX];
    int len[N_MAX];
    char S[L_MAX];
    struct Trie {
        int ch[L_MAX][26];
        int val[L_MAX];
        int sz;
        Trie() { sz = 1; memset(ch[0], 0, sizeof(ch[0])); }
        void init() { sz = 1; memset(ch[0], 0, sizeof(ch[0])); }
        int idx(char c) { return c - 'a'; }
        void insert(char*s, int v) {
            int u = 0, n = strlen(s);
            for (int i = 0; i < n; i++) {
                int c = idx(s[i]);
                if (!ch[u][c]) {
                    memset(ch[sz], 0, sizeof(ch[sz]));
                    val[sz] = 0;
                    ch[u][c] = sz++;
                }
                u = ch[u][c];
            }
            val[u] = v;
        }
        //找长度为len的字符串s的前缀
        void find(char *s, int len, vector<int>&ans) {
            int u = 0;
            for (int i = 0; i < len; i++) {
                if (s[i] == '')break;
                int c = idx(s[i]);
                if (!ch[u][c]) break;
                u = ch[u][c];
                if (val[u] != 0)ans.push_back(val[u]);
            }
        }
    };
    
    Trie trie;//不要放到main()下
    
    int main() {
        int Case = 1;
        while (scanf("%s%d", S, &n) !=EOF) {
            memset(dp, 0, sizeof(dp));
            trie.init();
            for (int i = 1; i <= n; i++) {
                char x[100];
                scanf("%s", x);
                len[i] = strlen(x);
                trie.insert(x, i);//将单词存入字典树,单词编号为i
            }
            int L = strlen(S);
            dp[L] = 1;
            for (int i = L - 1; i >= 0; i--) {
                vector<int>ans;//存储单词的编号
                trie.find(S + i, L - i, ans);
                for (int j = 0; j < ans.size(); j++) {
                    dp[i] = (dp[i] + dp[i + len[ans[j]]]) % MOD;
                }
            }
            printf("Case %d: %d
    ", Case++, dp[0]);
        }
        return 0;
    }
  • 相关阅读:
    centos7.6 安装与配置 MongoDB yum方式
    MongoDB 介绍
    centos 关闭selinux
    前端 HTML标签属性
    前端 HTML 标签嵌套规则
    前端 HTML 标签分类
    前端 HTML body标签相关内容 常用标签 表单标签 form里面的 input标签介绍
    前端 HTML body标签相关内容 常用标签 表单标签 form 表单控件分类
    前端 HTML form表单标签 select标签 option 下拉框
    POJ 1426
  • 原文地址:https://www.cnblogs.com/ZefengYao/p/8516576.html
Copyright © 2011-2022 走看看