[*] The number of dynamic programming Praying sequence of distinct subsequences

The general idea:

In fact, the essence is the "Praying sequence number." Obviously, this question is asked number, usually with dynamic programming to do.

This question and " seek the longest common subsequence " ( https://blog.csdn.net/m0_38033475/article/details/79492786 ) is somewhat similar. Similar is this: can the sequence is discontinuous. The difference is that: the longest common subsequence is just the two sequences to find the same sequence length of the longest; This question is a letter string must contain all substring, and ask, "Number Number / case" rather than length.

Contrast these two questions are more interesting:

  • Longest common subsequence approach:
for(int i=1;i<=s1.size();i++)
		{
			for(int j=1;j<=s2.size();j++)
			{
				if(s1[i]==s2[j]) 
					dp[i][j] = dp[i-1][j-1] + 1;//一定是这最后一个字母来作为公共子序列的结尾 
				else 
					dp[i][j] = max(dp[i][j-1],dp[i-1][j]);//一定不是它做结尾,则看之前的情况谁长谁上 
			}
		}
  • The title, the number of sequences :( Praying attention from "the number / situation" to think, rather than length!)

We need a two-dimensional array DP (i) (j) to record the length of the string of length i letter string number j is occurring , where the length of the head are counted, and traversing, holding length of the substring same, increment the letter string length, while the longest letter string to add a little length of the substring letter string calculation start again.

First we need to initialize the matrix, when the length of the substring is 0, 1 are all times, when the letter string length is 0, the number are all 0. When the letter string length of the substring are 0, the number is 1 (because They are empty, equal). Next, a different last letter and the last letter of the letter string if substrings, the description of the new letter string added letter no new possibilities, both can use the substring in the number of occurrences of short strings parent, so dp (i ) (J) = DP (I) (J-. 1) . If the last letter and the last letter of the parent string substring of the same, plus a description of the new female string of letters brought new possibilities, we not only count dp (i) (j-1 ), but also new count possibilities. So how do you calculate the new possibilities of it, in fact, when neither the last nor the mother of this last letter string substring letters, the number of substring appears, equivalent to all these possibilities we have to add a new possibility. Therefore, when DP (I) (J) = DP (I) (. 1-J) + DP (. 1-I) (J-. 1) .

I understand : For S [j]! = T [i] Needless to say, with the addition of this mother did not add this string of new characters, as in the case number; but for equal, the original number of cases is certainly to be considered, but would also like to add everyone to add this number as a master string ending common sequence, i.e. a final position of the common sequence number is set dead in this, so for dp [i-1] [j -1] where all numbers ( the same length, the same number of cases !!)

Programming Note:

initialization dp array is very important, critical condition for the beginning of good order, good initialization

② whether it is still seeking the longest common subsequence of this question, as it involves this i-1, so the index is traversed from the beginning , that is to say before the string began to make the deposit from 1, but in fact only a comparator for comparing the time T [i-1] and S [j-1] can.

programming when we must concentrate! ! Prior written S [i-1] for a long time did not find the bug. . . .

AC Code:

class Solution {
public:
    int numDistinct(string S, string T)
    {
        int dp[2000][2000]; //dp[i][j]:i表示子串长度,j表示母串长度
        //dp数组初始化
        for(int i=0;i<2000;i++)
        {
            for(int j=0;j<2000;j++)
            {
                dp[i][j]=0;
                dp[0][j]=1; //子串长度为0,即母串删去所有字符,出现1次
            }
        }
        
        int len_t = T.size();
        int len_s = S.size();
        for(int i=1;i<=len_t;i++)
        {
            for(int j=1;j<=len_s;j++)
            {
                if(T[i-1]!=S[j-1])
                    dp[i][j] = dp[i][j-1];
                else
                    dp[i][j] = dp[i][j-1] + dp[i-1][j-1]; //新增最后一个共同字符都定死到母串最后一个新字符的可能情况数
            }
        }
        return dp[len_t][len_s];
    }
};

 

 

 

The next day, we do a very similar topics, but also find the number of programs.

The general idea:

Soon he thought the number of dynamic planning practices seeking solutions only for the current of this new character, can represent a single word (dp [i] + = dp [i-1]) OR a combination with the (dp [i ] + DP = [I-2]) .

But still lacks consider some special cases, such as:

  • If this new character is '0', it alone can not express a word, must be combined with the previous.
  • Because of the need to set dynamic programming dp [0] = 1, but really if the string is empty, the output should be 0. Also, if the string is 0 starts, also can not represent any word of the output 0.

AC Code:

class Solution {
public:
    int numDecodings(string s) {
        if(s=="")
            return 0;
        if(s[0]=='0')
            return 0;
        long long dp[5000]={0};
        dp[0]=1;
        dp[1]=1;
        int len = s.size();
        for(int i=2;i<=len;i++)
        {
            if(s[i-1]>'0')
                dp[i] = dp[i-1]; //单个数字表示一个单词(还是有前提:不能为0)
            if((s[i-2]=='1' && s[i-1]<='9')||(s[i-2]=='2' && s[i-1]<='6')) //可以和前一个数字组合表示一个单词
            {
                dp[i] += dp[i-2];
            }
        }
        return dp[len];
    }
};

 

Guess you like

Origin blog.csdn.net/m0_38033475/article/details/92179093
Recommended