图论 弦
Problem statement:
问题陈述:
You are provided an input string S and the string "includehelp". You need to figure out all possible subsequences "includehelp" in the string S? Find out the number of ways in which the subsequence "includehelp" can be formed from the string S.
将为您提供输入字符串S和字符串“ includehelp”。 您需要找出字符串S中所有可能的子序列“ includehelp”。 找出从字符串S形成子序列“ includehelp”的方式的数量。
Input:
输入:
Input is the string s
输入是字符串s
Output:
输出:
Corresponding to each test case, print in a new line, a number denoting the number of ways in which we can form the subsequence "includehelp". Since output can be very large find the answer modulo 1000000007.
对应于每个测试用例,在新行中打印,该数字表示我们形成子序列“ includehelp”的方式的数量。 由于输出可能非常大,因此请找到模1000000007的答案。
Constraints:
限制条件:
Input String contains only lowercase English Letters and string length is 5000 at maximum.
输入字符串仅包含小写英文字母,并且字符串长度最大为5000。
Example:
例:
Input:
includehelp
Output:
1
Explanation:
There is only one instances of "includehelp"
in the above input string.
Input:
iincludehelp
Output:
2
Explanation:
There is two instances of "includehelp"
in the above input string.
Solution Approach:
解决方法:
Let the input string be, s and t="includehelp"
This problem can be solved by recursion.
So we have,
string s: the input string
string t: the second string ("includehelp")
starts : start point of string s
srartt : start point of string t, ("includehelp")
m: length of input string
11: length of string t,"includehelp"
MOD: 1000000009
Now, how can we generate a recursive relation?
现在,我们如何生成递归关系?
Say starts=i where 0<=i<m & startt=j where 0<=j<11
说starts = i ,其中0 <= i <m&startt = j ,其中0 <= j <11
Say,
说,
s[starts]=t[startt] that means both have same character,
s [starts] = t [startt]表示两个字符相同,
Now we have two options,
现在我们有两个选择,
- starts+1, starts + 1 , startt+1 which means we are looking for the same occurrence, we want to check for other characters as well.startt + 1 ,这意味着我们正在寻找相同的事件,我们也想检查其他字符。
- starts+1, starts + 1和startt which means we are looking for another different occurrence.startt ,这意味着我们正在寻找另一个不同的事件。
s[starts]!=t[startt]
s [starts]!= t [startt]
Now we have only one option which is check for
现在我们只有一个选项可以检查
starts+1, startt as we need to look for different occurrence only.
starts + 1 , startt,因为我们只需要查找不同的事件。
Function:
jumbleString(string s,string t,int starts,int startt,int m)
// enter substring is matched
if startt==11
return 1;
// enter string has been searched with out match
if starts==m
return 0;
if(s[starts]!=t[startt])
//only one option as we discussed
return jumbleString(s,t,starts+1,startt,m)%MOD;
else
// both the options as we discussed
return (jumbleString(s,t,starts+1,startt+1,m)%MOD +
jumbleString(s,t,starts+1,startt,m)%MOD)%MOD
The above recursion will generate many overlapping subproblems and hence we need to use dynamic programming.
上面的递归将产生许多重叠的子问题,因此我们需要使用动态编程。
Let's convert the recursion to DP.
让我们将递归转换为DP。
Step 1: initialize DP table,
步骤1:初始化DP表,
int dp[m+1][12];
Step 2: convert step1 of recursive function,
步骤2:转换递归函数的step1,
for i=0 to 11 dp[0][i]=0;
Step 3: convert step 2 of recursive function,
步骤3:转换递归函数的步骤2,
for i=0 to m dp[i][0]=1;
Step 4: Fill the DP table which is similar to step3 of the recursion function,
步骤4:填写DP表,该表类似于递归函数的步骤3,
for i=1 to m for j=1 to 11 if s[i-1]==t[j-1] dp[i][j]=(dp[i-1][j]+dp[i-1][j-1])%MOD else dp[i][j]=dp[i-1][j] end for end for
Step5: return dp[m][11] which is the result.
步骤5:返回结果dp [m] [11] 。
The above DP technique is known as the tabulation process. We can introduce memorization as well, known as the top-down approach. Where we store every computed subproblem and while computing first we look up our DP table whether sub-problem is already solved or not. Check the below top-down implementation for the above problem.
上述DP技术称为制表过程。 我们也可以引入记忆,称为自顶向下方法。 我们存储每个计算出的子问题的位置,并且在进行第一次计算时,无论子问题是否已解决,我们都会查看DP表。 检查以下自上而下的实现是否存在上述问题。
C++ Implementation:
C ++实现:
#include <bits/stdc++.h>
using namespace std;
int dp[1001][12];
int jumbled(string s1, string s2, int i, int j, int n, int m)
{
if (j == m) {
return 1;
}
if (i == n && j != m)
return 0;
// if subproblem already solved
if (dp[i][j] != -1)
return dp[i][j];
if (s1[i] == s2[j]) {
dp[i][j] = jumbled(s1, s2, i + 1, j + 1, n, m) + jumbled(s1, s2, i + 1, j, n, m);
}
else {
dp[i][j] = jumbled(s1, s2, i + 1, j, n, m);
}
return dp[i][j];
}
int main()
{
int n;
string s2 = "includehelp";
string s1;
cout << "Input string: ";
cin >> s1;
n = s1.length();
for (int i = 0; i < n; i++) {
for (int j = 0; j < 11; j++)
dp[i][j] = -1;
}
cout << "We can jumble " << jumbled(s1, s2, 0, 0, n, 11) << " of ways." << endl;
return 0;
}
Output:
输出:
Input string: iincludehelp
We can jumble 2 of ways.
翻译自: https://www.includehelp.com/icp/jumbled-strings.aspx
图论 弦