现在的位置: 首页 > 综合 > 正文

UVa 10069 – Distinct Subsequences

2019年11月08日 ⁄ 综合 ⁄ 共 4114字 ⁄ 字号 评论关闭

dp+大数加法。

设母串的长度为 j, 子串的长度为 i,我们要求的就是长度为 i 的字串在长度为 j 的母串中出现的次数。

(1)若母串的最后一个字符与子串的最后一个字符不同,则长度为 i 的子串在长度为 j 的母串中出现的次数就是母串的前 j - 1 个字符中子串出现的次数,即 str[i][j] = str[i][j - 1];

(2)若母串的最后一个字符与子串的最后一个字符相同,那么除了前 j - 1 个字符出现子串的次数外,还要加上子串的前 i - 1 个字符在母串的前 j - 1 个字符中出现的次数(再加上当前相等的这个字符其长度就可以凑成完整的字串长度),即 str[i][j] = str[i][j - 1]
+ str[i - 1][j - 1]。

#include<iostream>
#include<map>
#include<string>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn = 200;
struct bign{
  int len, s[maxn];

  bign() {
    memset(s, 0, sizeof(s));
    len = 1;
  }

  bign(int num) {
    *this = num;
  }

  bign(const char* num) {
    *this = num;
  }

  bign operator = (int num) {
    char s[maxn];
    sprintf(s, "%d", num);
    *this = s;
    return *this;
  }

  bign operator = (const char* num) {
    len = strlen(num);
    for(int i = 0; i < len; i++) s[i] = num[len-i-1] - '0';
    return *this;
  }

  string str() const {
    string res = "";
    for(int i = 0; i < len; i++) res = (char)(s[i] + '0') + res;
    if(res == "") res = "0";
    return res;
  }

  bign operator + (const bign& b) const{
    bign c;
    c.len = 0;
    for(int i = 0, g = 0; g || i < max(len, b.len); i++) {
      int x = g;
      if(i < len) x += s[i];
      if(i < b.len) x += b.s[i];
      c.s[c.len++] = x % 10;
      g = x / 10;
    }
    return c;
  }

  void clean() {
    while(len > 1 && !s[len-1]) len--;
  }

  bign operator * (const bign& b) {
    bign c; c.len = len + b.len;
    for(int i = 0; i < len; i++)
      for(int j = 0; j < b.len; j++)
        c.s[i+j] += s[i] * b.s[j];
    for(int i = 0; i < c.len-1; i++){
      c.s[i+1] += c.s[i] / 10;
      c.s[i] %= 10;
    }
    c.clean();
    return c;
  }

  bign operator - (const bign& b) {
    bign c; c.len = 0;
    for(int i = 0, g = 0; i < len; i++) {
      int x = s[i] - g;
      if(i < b.len) x -= b.s[i];
      if(x >= 0) g = 0;
      else {
        g = 1;
        x += 10;
      }
      c.s[c.len++] = x;
    }
    c.clean();
    return c;
  }

  bool operator < (const bign& b) const{
    if(len != b.len) return len < b.len;
    for(int i = len-1; i >= 0; i--)
      if(s[i] != b.s[i]) return s[i] < b.s[i];
    return false;
  }

  bool operator > (const bign& b) const{
    return b < *this;
  }

  bool operator <= (const bign& b) {
    return !(b > *this);
  }

  bool operator == (const bign& b) {
    return !(b < *this) && !(*this < b);
  }

  bign operator += (const bign& b) {
    *this = *this + b;
    return *this;
  }
};

istream& operator >> (istream &in, bign& x) {
  string s;
  in >> s;
  x = s.c_str();
  return in;
}

ostream& operator << (ostream &out, const bign& x) {
  out << x.str();
  return out;
}
bign dp[110][10010];
int main()
{
	int T,i,j,lena,lenb;
	string a,b;
	cin>>T;
	while(T--)
	{
		cin>>a>>b;
		lena=a.length();
		lenb=b.length();
		for(i=1;i<=lenb;i++)
		{
			for(j=i;j<=lena;j++)
				if(a[j-1]!=b[i-1])
					dp[i][j]=dp[i][j-1];
				else
				{
					dp[i][j]=dp[i][j-1]+dp[i-1][j-1];
					if(i==1)//第一个字母相同时,必然要+1 
						dp[i][j]=dp[i][j]+1;
				}
		}
		cout<<dp[lenb][lena]<<endl;
	}
	return 0;
}

Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu

SubmitStatus

Description

Download as PDF

Problem E

Distinct Subsequences

Input: standard input

Output: standard output

 

A subsequence of a given sequence is just the given sequence with some elements (possibly none) left out. Formally, given a sequenceX=x1x2xm, another sequenceZ=z1z2zk
is a subsequence ofX if there exists a strictly increasing sequence
<i1, i2, …, ik> of indices ofX such that for all
j = 1, 2, …, k, we havexij=zj. For example,Z=bcdb is a subsequence of
X=abcbdab with corresponding index sequence< 2, 3, 5, 7 >.

In this problem your job is to write a program that counts the number of occurrences ofZ in
X as a subsequence such that each has a distinct index sequence.

 

Input

The first line of the input contains an integer N indicating the number of test cases to follow.

The first line of each test case contains a string X, composed entirely of lowercase alphabetic characters and having length no greater than 10,000. The second line contains another stringZ having length
no greater than 100 and also composed of only lowercase alphabetic characters. Be assured that neitherZ nor any prefix or suffix of
Z will have more than 10100 distinct occurrences inX as a subsequence.

 

Output

For each test case in the input output the number of distinct occurrences of
Z
in X as a subsequence. Output for each input set must be on a separate line.

 

Sample Input

2
babgbag
bag
rabbbit
rabbit

 

Sample Output

5
3

____________________________________________________________________________________
Rezaul Alam Chowdhury

Source

Root :: AOAPC I: Beginning Algorithm Contests (Rujia Liu) ::
Volume 5. Dynamic Programming

Root :: Competitive Programming 3: The New Lower Bound of Programming Contests (Steven & Felix Halim) :: More Advanced Topics :: More Advanced DP Techniques ::DP
level 2

Root :: Programming Challenges (Skiena & Revilla) ::
Chapter 11

Root :: Prominent Problemsetters ::
Rezaul Alam Chowdhury

Root :: Competitive Programming 2: This increases the lower bound of Programming Contests. Again (Steven & Felix Halim) :: More Advanced Topics :: More Advanced Dynamic Programming ::The
More Challenging Ones

抱歉!评论已关闭.