zoukankan      html  css  js  c++  java
  • 九峰与子序列 题解(dp+hash)

    题目链接

    题目大意

    给你\(n(n\leq 40)\)个字符串\(a(\sum_{i=1}^{i=n}len[a[i]]\leq 5e6)\)和一个匹配串\(s(len[s]\leq 5e6)\)

    要你求有多少种\(a\)的子序列拼接起来等于s

    题目思路

    个人感觉属于一个套路dp,然后自己居然没想出来。。

    \(dp[i][j]\)表示前i个子序列匹配到s串第j位的方案数

    \(dp[i][j]=dp[i-1][j]+dp[i-1][j-len[i]]*(a[i]==s.substr(j-len[i]+1,len[i])))\)

    判断是否相同用hash处理即可

    dp省去第一维,优化空间,注意dp时要倒序

    代码

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define debug cout<<"I AM HERE"<<endl;
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> pii;
    const int maxn=5e6+5,inf=0x3f3f3f3f;
    //int mod=1e9+7;
    const int eps=1e-3;
    ull base=1e9+7;
    ull power[maxn],pre[maxn];
    ull a[50];
    int n,d;
    int len[50];
    char s[maxn],temp[maxn];
    ll dp[maxn];
    void init(){//hash前缀
        power[0]=1;//别忘了
        for(int i=1;i<=d;i++){
            power[i]=power[i-1]*base;
        }
        for(int i=1;i<=d;i++){
            pre[i]=pre[i-1]*base+s[i]-'a'+1;
        }
    }
    ull gethash(int l,int r){
        return pre[r]-pre[l-1]*power[r-l+1];
    }
    signed main(){
        scanf("%d %s",&n,s+1);
        d=strlen(s+1);
        init();
        for(int i=1;i<=n;i++){
            scanf("%s",temp+1);
            len[i]=strlen(temp+1);
            for(int j=1;j<=len[i];j++){ //预处理每个串的hash值
                a[i]=a[i]*base+temp[j]-'a'+1;
            }
        }
        dp[0]=1;
        for(int i=1;i<=n;i++){
            for(int j=d;j>=len[i];j--){
                // [j-len[i]+1,j]
                if(a[i]==gethash(j-len[i]+1,j)){
                    dp[j]+=dp[j-len[i]];
                }
            }
        }
        printf("%lld\n",dp[d]);
        return 0;
    }
    
    
    不摆烂了,写题
  • 相关阅读:
    【就业】腾讯VS百度
    MySQL基础知识
    PHP读取远程文件并保存
    【GTK3.0】背景设置
    【GTK】信号量(signal)大全
    c# 调用win32 api
    PHP写窗体程序
    一个苏州IT人的5年挨踢经历面试篇(之二)
    【c++ Primer 】 4.10复习题 12题(int)、(int&)和(int*)
    线段树技巧
  • 原文地址:https://www.cnblogs.com/hunxuewangzi/p/14419262.html
Copyright © 2011-2022 走看看