zoukankan      html  css  js  c++  java
  • UVALive

    题意:

    给定一篇长度为L的小写字母文章, 然后给定n个字母, 问有多少种方法用这些字母组成文章。

    思路:

    用dp[i]来表达[i , L]的方法数, 那么dp[i] 就可以从dp[len(x) + i]转移过来, 注意dp[L+1]要初始化为1.

    递推写法

    #include <bits/stdc++.h>
    using namespace std;
    const int maxN = 3e5 + 7;
    const int mod =  20071027;
    char in[maxN];
    int n;
    struct Trie {
        int ch[maxN][26];
        int val[maxN];
        int sz;
        void Init(){sz = 1; memset(ch[0], 0, sizeof(ch[0])); memset(val, 0, sizeof(val));}
        int idx(char c) {return c - 'a';}
        void Insert(char *s){
            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] = n;
        }
    
    }tree;
    long long dp[maxN];
    int main(){
    //    freopen("1.txt","r", stdin);
        int kase = 1;
        while(~scanf("%s", in)){
            tree.Init();
            memset(dp , 0 , sizeof(dp));
            scanf("%d", &n);
            char word[100];
            for(int i = 0; i < n; i++){
                scanf("%s", word);
                tree.Insert(word);
            }
            int len = strlen(in);
            dp[len] = 1;
            for(int pos = len ; pos >= 0; pos--){
                int u = 0;
                for(int i = pos, wordLen = 1; i < len; i++, wordLen++){
                    int c = tree.idx(in[i]);
                    if(tree.ch[u][c] == 0) break;
                    u = tree.ch[u][c];
                    if(tree.val[u] != 0){
                        dp[pos] += dp[pos + wordLen];
                        dp[pos] %= mod;
                    }
                }
            }
            printf("Case %d: %lld
    ", kase++, dp[0]);
        }
    
        return 0;
    }

    记忆化搜索

    #include <bits/stdc++.h>
    using namespace std;
    const int maxN = 2e6 + 7;
    const int mod =  20071027;
    char in[maxN];
    int n;
    struct Trie {
        int ch[maxN][26];
        int val[maxN];
        int sz;
        void Init(){
            sz = 1;
            memset(ch[0], 0, sizeof(ch[0]));
            memset(val, 0, sizeof(val));
        }
        int idx(char c) {return c - 'a';}
        void Insert(char *s){
            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] = n;
        }
    
    }tree;
    
    long long dp[maxN];
    int dfs(int pos){
        int temp = pos;
        if(dp[pos] > 0) return dp[pos];
        int ret = 0;
        int adr = 0;
        while(tree.ch[adr][in[pos] - 'a']){
            adr = tree.ch[adr][in[pos] - 'a'];
            if(tree.val[adr] != 0){
                ret = (ret + dfs(pos + 1)) % mod;
            }
            pos ++;
    
        }
        dp[temp] = ret;
        return ret;
    }
    
    int main(){
        freopen("1.txt","r", stdin);
        int ncase = 1;
        while(~scanf("%s", in)){
            tree.Init();
            scanf("%d", &n);
            char word[100];
            for(int i = 0; i < n; i++){
                scanf("%s", word);
                tree.Insert(word);
            }
    
            int l = strlen(in);
            for(int i = 0;i <= l; i ++)dp[i] = 0;
            dp[l] = 1;
            printf("Case %d: %d
    ",ncase ++ , dfs(0));
        }
    
        return 0;
    }
  • 相关阅读:
    PEP8 Python 编码规范整理
    github操作
    重零开始,写一个股票交易项目(1)
    矢量地图质量检查现状与需求(2篇)
    导航数据质量评价相关
    测绘数据国内外现状概述
    机器的反叛-机器的智能会超越人类吗?
    标签要素调用CSS样式优先级说明
    内存碎片概念及主要避免方式
    关于年终述职总结
  • 原文地址:https://www.cnblogs.com/Jadon97/p/9445490.html
Copyright © 2011-2022 走看看