您的位置:首页 > 其它

【LA3516】Exploring Pyramids——动态规划+乘法原理

2016-03-28 08:21 405 查看
Archaeologists have discovered a new set of hidden caves in one of the Egyptian pyramids. The

decryption of ancient hieroglyphs on the walls nearby showed that the caves structure is as follows.

There are n caves in a pyramid, connected by narrow passages, one of the caves is connected by a

passage to the outer world. The system of the passages is organized in such a way, that there is exactly

one way to get from outside to each cave along passages. All caves are located in the basement of the

pyramid, so we can consider them being located in the same plane. Passages do not intersect. Each

cave has its walls colored in one of several various colors.

The scientists have decided to create a more detailed description of the caves, so they decided to

use an exploring robot. The robot they are planning to use has two types of memory — the output

tape, which is used for writing down the description of the caves, and the operating memory organized

as a stack.

The robot first enters the cave connected to the outer world along the passage. When it travels

along any passage for the first time, it puts its description on the top of its stack. When the robot

enters any cave, it prints the color of its walls to its output tape. After that it chooses the leftmost

passage among those that it has not yet travelled and goes along it. If there is no such passage, the

robot takes the passage description from the top of its stack and travels along it in the reverse direction.

The robot’s task is over when it returns to the outside of the pyramid. It is easy to see that during

its trip the robot visits each cave at least once and travels along each passage exactly once in each

direction.

The scientists have sent the robot to its mission. After it returned they started to study the output

tape. What a great disappointment they have had after they have understood that the output tape

does not describe the cave system uniquely. Now they have a new problem — they want to know how

many different cave systems could have produced the output tape they have. Help them to find that

out.

Since the requested number can be quite large, you should output it modulo 1 000 000 000. Please

note, that the absolute locations of the caves are not important, but their relative locations are important,

so the caves (c) and (d) on the picture below are considered different.



Input

The input file contains the output tape that the archaeologists have. The output tape is the sequence of

colors of caves in order the robot visited them. The colors are denoted by capital letters of the English

alphabet. The length of the tape does not exceed 300 characters.

Output

Output one integer number — the number of different cave systems (modulo 1 000 000 000) that could

produce the output tape.

Sample Input

ABABABA

AB

Sample Output

5

0

题意:给你一个多叉的树,每个节点的子节点都有左右之分,每次尽量先向左走,走不通了,再回溯,把遇到的字符记录下来得到一个序列,问有多少种树对应这这种序列。

分析:由于是记录遍历顺序的字母,所以对于一颗树的遍历的序列第一个字母和最后一个字母一定相同。

Dp[i][j]表示子序列Si,Si+1,Si+2⋯,Sj对应的树的个数,则边界对应的条件就是Dp[i][i]=1,且当i!=j的时候如果S[i]!=S[j],则Dp[i][j]=0,其他的情况,则第一颗子树的的序列是Si+1,Si+2⋯,Sk−1,其他的序列对应着序列为Sk,Sk+1,SK+2,⋯Sj,对应的总的个数为Dp[i+1][k−1]×DP[k][j],所以Dp[i][j]=∑k=i+2jDp[i+1][k−1]⋅Dp[k][j]Dp[i][j]表示子序列S_i,S_{i+1},S_{i+2} \cdots ,S_j对应的树的个数,则边界对应的条件就是Dp[i][i] = 1,且当i != j的时候 \\ 如果 S[i]!=S[j],则Dp[i][j] = 0,其他的情况,则第一颗子树的的序列是S_{i+1},S_{i+2} \cdots, S_{k-1},其他的序列对应着序列为 \\ S_k,S_{k+1},S_{K+2}, \cdots S_j,对应的总的个数为Dp[i+1][k-1]\times DP[k][j],所以Dp[i][j] = \sum \limits_{k=i+2}^jDp[i+1][k-1]\cdot Dp[k][j]

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <algorithm>

using namespace std;
typedef long long LL;

const LL Mod = 1000000000;

char s[350];

LL Dp[350][350];

void DFS(int L,int R)
{
if(L==R)
{
Dp[L][R] = 1; return ;
}

if( s[L] != s[R])
{
Dp[L][R] = 0;

return ;
}

if(Dp[L][R] !=-1)
{
return ;
}

LL ans = 0;

for(int i = L+2;i<=R;i++)
{
DFS(L+1,i-1);

DFS(i,R);

ans = (ans+(Dp[L+1][i-1]*Dp[i][R])%Mod)%Mod;
}

Dp[L][R] = ans;
}

int main()
{
while(~scanf("%s",s))
{
memset(Dp,-1,sizeof(Dp));

DFS(0,strlen(s)-1);

printf("%lld\n",Dp[0][strlen(s)-1]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: