Arthur's Language

本文介绍了一个编程挑战,任务是在字符串S中找到通过删除字符获得目标字符串w的所有不同方式,并给出了解决该问题的一种动态规划算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CF-101628-A

Arthur is an extremely important person and rarely has the time to talk. To minimize the time spent with words, he developed his own language, which he uses on a daily basis. However, it’s very hard to understand whatever comes out of his mouth.

In order to improve his interaction with the rest of the world, Arthur has asked the Narratives Industrial Complex (CIN in Portuguese) to develop a program which receives a speech S produced by Arthur and a pattern w and prints how many distinct ways we can obtain w by only removing characters from S. Two ways are considered distinct if there is an index 0 ≤ i < |S| such as Si is present in one and not in the other.

Since you are considered the most experienced programmer in CIN, your team has trusted you the task of writing this program.

Input

The first line consists of a string S(1 ≤ |S| ≤ 105), representing Arthur’s speech. S contains only lower and upper case letters.
The second and last line consists of a string w(1 ≤ |w| ≤ 10), the pattern to be searched.

Output

Print a single integer: The number of distinct ways to obtain w by removing letters from S. Because this number can be large, print the remained of this number divided by 1000000007 = 109 + 7

Examples

Input

weewrshkim
sim

Output

1

Input

qqqaaabbbcccfffrrr
qabcfr

Output

729


题意

有两个字符串:a,b
在a中移除一些字符可得到b
问:有多少中方案


题解

因为是移除一些字符,所以原串的顺序是不变的
dp递推:
dp[i][j]表示模式串中第i个字符匹配到匹配串中第j个字符时有多少方案数
故dp[a.size()-1]dp[b.size()-1]即为所求

#include<iostream>
#include<string>
using namespace std;
typedef long long ll;
ll dp[20][100000 + 50];
const ll MOD = 1e9 + 7;
int main()
{
    string s, p;
    cin >> s >> p;
    for (int i = 0; i < s.size(); i++)//预处理第一行
    {
        if (i)
            dp[0][i] = dp[0][i - 1];
        if (s[i] == p[0])
        {
            dp[0][i]++;
        }
    }//是一个前缀和
    for (int i = 1; i < p.size(); i++)
    {
        for (int j = i; j < s.size(); j++)
        {
            if (j)
                dp[i][j] = dp[i][j - 1];//维护前缀和
            if (p[i] == s[j])
            {
                dp[i][j] += dp[i - 1][j - 1];//不能是dp[i-1][j]
                dp[i][j] %= MOD;
            }
        }
    }
    cout << dp[p.size() - 1][s.size() - 1] % MOD << endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值