http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1641
这个题确实是个递推+乘法计数原理 不过思维很强。
题目大意是给一串字符串ABABABA比如这样子 让你把这个字符串以类似前序遍历的方式来解读,看到底生成了多少棵树。
刚拿到的时候是懵逼的 但是一看就是个区间题 区间dp就找公式了 然后就化成小问题 也就是划分左子树的种类乘上剩下的右子树的数量
其中d[i][j]表示字符串从i到j的子树数量
另外蓝书把这个放在数学基础确实太难了,你难就难吧,你还不说是dp,你不说是dp也就罢了,你题解还写错了。。。
下面上代码
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn = 300 + 10;
const int MOD = 1000000000;
typedef long long LL;
char S[maxn];
LL d[maxn][maxn];
LL dp(int i,int j){
if(i == j) return d[i][j] = 1;
if(S[i] != S[j]) return d[i][j] = 0;
LL ans = d[i][j];
if(ans >= 0) return ans;
ans = 0;
for(int k = i + 2;k <= j;k++){
if(S[i] == S[k])
ans = (ans + dp(i + 1,k - 1)*dp(k,j)) % MOD;
}
return d[i][j] = ans;
}
int main(){
while(scanf("%s",S) !=EOF){
memset(d,-1,sizeof(d));
printf("%lld\n",dp(0,strlen(S) - 1));
}
return 0;
}