UVa 10069 Distinct Subsequences(经典DP)
题意:
给定2个字符串a, b,求b在a中出现的次数。要求可以是不连续的,但是b在a中的顺序必须和b以前的一致。
思路:
类似于数字分解的题目。dp[i][j]表示:b的前j个字符在a的前i个字符中出现的次数。
似乎这种表示方法司空见惯,但是一开始我还真没能搞懂如何去递推。事情的真相是:
如果a[i] == b[j]则 dp[i][j] = dp[i-1][j] + dp[i-1][j-1]
如果a[i] != b[j]则 dp[i][j] = dp[i-1][j]
有种似曾相识的感觉,没错,这种递推的策略就和POJ 1221数字分解差不多:给定数n,把其分解成1-m数字相加之和。
其实本题可以转换成一维的数组,但是初始化有点撇脚。精力有限,于是就没这么做。
参考了博客http://www.cppblog.com/syhd142/articles/117881.html
强大的c++封装与重载,慢慢的掌握。
ps:上次师兄面试说问到类中const和非const的区别。在本题中可以比较好的体现:
const修饰的函数只能const类型的才能调用。非const只能调用非const函数。但是关于const的理解还有待于加深。
#include <cstdio>
#include <cstdlib>
#include <cstring>
const int MAXN = 10010;
const int BASE = 1000000000;
struct bignum {
int len;
int data[30];
bignum() : len(0) { }
bignum(const bignum &v) : len(v.len) {
memcpy(data, v.data, len * sizeof(int));
}
bignum(int v) : len(0) {
while (v > 0)
data[len++] = v % BASE, v /= BASE;
}
bignum &operator = (const bignum &v) {
len = v.len;
memcpy(data, v.data, len * sizeof(int));
return *this;
}
int &operator [] (int i) {
return data[i];
}
int operator [] (int i) const {
return data[i];
}
};
bignum operator + (const bignum &a, const bignum &b)
{
bignum r;
int i, carry = 0;
for (i = 0; i < a.len || i < b.len || 0 < carry; ++i)
{
if (i < a.len)
carry += a[i];
if (i < b.len)
carry += b[i];
r[i] = carry % BASE;
carry /= BASE;
}
r.len = i;
return r;
}
bignum dp[MAXN][105];
char src[MAXN], dst[MAXN];
int main()
{
int cases;
scanf("%d%*c", &cases);
while (cases--)
{
gets(src + 1);
gets(dst + 1);
int ls, ld;
ls = strlen(src + 1);
ld = strlen(dst + 1);
int c = 0;
for (int i = 1; i <= ls; ++i)
if (src[i] == dst[1])
dp[i][1] = bignum(++c);
else
dp[i][1] = bignum(c);
for (int i = 2; i <= ls; ++i)
{
for (int j = 2; j <= ld; ++j)
{
dp[i][j] = dp[i-1][j];
if (src[i] == dst[j])
dp[i][j] = dp[i][j] + dp[i-1][j-1];
}
}
for (int i = dp[ls][ld].len - 1; i >= 0; --i)
printf("%d", dp[ls][ld][i]);
printf("\n");
}
return 0;
}
-------------------------------------------------------
kedebug
Department of Computer Science and Engineering,
Shanghai Jiao Tong University
E-mail: kedebug0@gmail.com
GitHub: http://github.com/kedebug
-------------------------------------------------------