リンク:
https://www.acwing.com/problem/content/description/286/
質問の意味:
ピラミッドを探索しながら、非常に古風な話ですが、ピラミッドの麓に探検家のチームがまだあります。
研究の年後、ピラミッドの科学者の内部構造が理解しています。
まず、ピラミッドでも部屋から部屋の通路で、いくつかの部屋で構成します。
サイドチャネルとして見ノードとして見られる部屋は、その後、全体ピラミッドサブツリーノードの間で規則的、ルート付きツリー構造を提示した場合、ピラミッド根に一つだけの入り口があります。
さらに、各部屋の壁は、複数の色でコーティングされています。
探検隊はさらに、彼らは特別に設計されたロボットを使用しているためにピラミッドの構造を理解することを意図しています。
このロボットは深さ優先探索後ピラミッドの入り口からピラミッドを入力します。
部屋に各ロボットは、(それを入力または返却するのは初めてであるかどうか)、部屋の色を記録します。
最後に、ロボットは、ピラミッドの入り口から終了します。
明らかに、ロボットが各部屋に少なくとも一度訪問し、ちょうど2倍(一回、各方向で)を介して各チャネルます、そしてロボットは色のシーケンスを取得します。
しかし、遠征は、色配列が一意ピラミッドの構造を決定しないことを見出しました。
今、彼らはあなたがそれらを与えられた色の順序のために、可能な構造の数は、このシーケンスを取得し、計算を支援したいと思います。
結果は非常に大きくなる可能性があるので、あなただけの剰余後109の出力値に答える必要があります。
アイデア:
F LRの組成に[L] [R]、それぞれについてLR、Lがルートである場合、他の部分についてのK + 1-Rの後ろのサブツリーにL + 1-Kをさせ、再帰的に解決、およびメモリ検索。
コード:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MOD = 1e9;
char s[500];
LL F[500][500];
LL Dfs(int l, int r)
{
// cout << l << ' ' << r << endl;
if (l > r)
return 0;
if (s[l] != s[r])
return 0;
if (l == r)
return 1;
if (F[l][r] != -1)
return F[l][r];
F[l][r] = 0;
for (int k = l+1;k < r;k++)
F[l][r] = (F[l][r] + Dfs(l+1, k)*Dfs(k+1, r))%MOD;
return F[l][r];
}
int main()
{
scanf("%s", s+1);
int n = strlen(s+1);
memset(F, -1, sizeof(F));
printf("%lld\n", Dfs(1, n));
return 0;
}