您的位置:首页 > 其它

《算法竞赛-训练指南》第二章-2.4-LA 3516

2013-08-10 11:33 204 查看
这几天一直静不下心,做题一点都没有效率。也可能是动态规划这边的题目实在是有点难度,所以有时候搞一道题目都弄的很长时间,很悲催。在一个就是自己的智商不怎么样。

这道题目的意思是给你一个序列,求出以这个序列为准的,所有的树。

这样就得实用递归求解了,也就是每个树都可以分成左子树和右子树,这两种书其实又可以看成是独立的树。所以就分成了子问题求解,非常的不错。

递推方程就是 dp(i, j) = sum(dp(i + 1, k - 1) * dp(k, j))。当然k是从1 - len - 1的。这样就可以把所有的树都可以求出来了。就是我用的是vis记忆化搜索,也可以使d[i] = -1,记忆化搜索。

贴出代码:

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>

using namespace std;

const int MOD = 1000000000;

char str[333];

int d[333][333];

int vis[333][333];

int dp(int i, int j)
{
if (vis[i][j])
{
return d[i][j];
}
vis[i][j] = 1;
if (i == j)
{
d[i][j] = 1;
return 1;
}
if (str[i] != str[j])
{
d[i][j] = 0;
return 0;
}
int& ans = d[i][j];
for (int k = i + 2; k <= j; k++)
{
if (str[i] == str[k])
{
ans = (ans + (long long)dp(i + 1, k - 1) * (long long)dp(k, j)) % MOD;
}
}
return ans;
}

int main()
{
while (scanf("%s", str) != EOF)
{
int len = strlen(str);
memset(vis, 0, sizeof(vis));
memset(d, 0, sizeof(d));
printf("%d\n", dp(0, len - 1));
}
// system("pause");
return 0;
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: