加密

【问题描述】

  有一种不讲道理的加密方法是: 在字符串的任意位置随机插入字符。 相应的,不讲道理的解密方法就是从字符串中恰好删去随机插入的那些字符。给定原文s和加密后的字符串t,求t有多少子串可以通过解密得到原文s。

【输入格式】

  输入第一行包含一个字符串t,第二行包含一个字符串s。

【输出格式】

  输出一行,包含一个整数,代表可以通过解密得到原文的t的子串的数量。

【样例输入】

  abcabcabc

  cba

【样例输出】

  9

【样例解释】

  用[l,r]表示子串开头结尾的下标(从 0 开始编号) ,这 9 种方案是:[0,6],[0,7],[0,8],[1,6],[1,7],[1,8],[2,6],[2,7],[2,8]

【数据规模和约定】

  对于30%的数据,|t| ≤1000。

  对于100%的数据,1 ≤ |t| ≤ 300,000,1 ≤ |s| ≤ 200。

#include<cstdio>
#include<iostream>
#include<cstring> 
#include<algorithm>
#define ll long long
#define N  300100
#define M 310
using namespace std;
int n,m;
ll ans(0);
int f[M]={0},a[N];
char s[M],t[N];
int main()
{
    freopen("encrypt.in","r",stdin);
    freopen("encrypt.out","w",stdout);
    
    
    scanf("%s%s",t+1,s+1);
    n=strlen(t+1);
    m=strlen(s+1);
    for (int i=1;i<=n;i++)
      {
           f[0]=i;//i前的数每减少一个数就能形成一个新序列 
           for (int j=m;j>=1;j--)
             if (t[i]==s[j]) f[j]=f[j-1]; //一个满足条件的序列时,与s[1]相等的数越靠后所能形成的序列个数更多。
                                        //不断更新最大值。 
           ans+=f[m]; 
      }
    printf("%I64d",ans);
    
    fclose(stdin);
    fclose(stdout);
    
    return 0;
}
dp
原文地址:https://www.cnblogs.com/sjymj/p/6057582.html