您的位置:首页 > 其它

【DP】 HDOJ 5370 Tree Maker

2015-08-12 19:55 190 查看
先O(n^3)的预处理,然后每次计算都是O(n)的。。。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;

const int maxn = 505;
const int mod = 1e9+7;

struct node
{
int size;
node *fa, *ch[2];
}pool[maxn], *tail, *root;

LL h[maxn];
LL dp[maxn][maxn];
queue<node*> q;
int tree, cnt, m;

node* newnode(int size, node *f)
{
tail->size = size;
tail->fa = f;
tail->ch[0] = tail->ch[1] = 0;
return tail++;
}

void init()
{
tail = pool;
root = newnode(0, NULL);
}

LL powmod(LL a, LL b)
{
LL res = 1, base = a;
while(b) {
if(b & 1) res = res * base % mod;
base = base * base % mod;
b >>= 1;
}
return res;
}

void _init()
{
h[0] = h[1] = 1;
for(int i = 2; i < maxn; i++) h[i] = h[i-1] * (4 * i - 2) % mod * powmod(i+1, mod-2) % mod;

dp[0][0] = 1;
for(int i = 1; i < maxn; i++)
for(int j = 0; j < maxn; j++)
for(int k = 0; k <= j; k++)
dp[i][j] = (dp[i][j] + dp[i-1][j-k] * h[k] % mod) % mod;
}

void dfs(node *o)
{
cnt--;
if(o->ch[0]) {
if(o->ch[0]->size) q.push(o->ch[0]);
else dfs(o->ch[0]);
}
else tree++;

if(o->ch[1]) {
if(o->ch[1]->size) q.push(o->ch[1]);
else dfs(o->ch[1]);
}
else tree++;
}

void bfs()
{
LL ans = 1;
dfs(root);
while(!q.empty()) {
node *u = q.front();
q.pop();
cnt = u->size;
tree = 0;
dfs(u);
ans = ans * dp[tree][cnt] % mod;
}
printf("%lld\n", ans);
}

void work()
{
int op, sz;
node *u = root;
for(int i = 1; i <= m; i++) {
scanf("%d", &op);
if(op == 0) u = u->fa;
if(op == 1) {
if(!u->ch[0]) u->ch[0] = newnode(0, u);
u = u->ch[0];
}
if(op == 2) {
if(!u->ch[1]) u->ch[1] = newnode(0, u);
u = u->ch[1];
}
if(op == 3) {
scanf("%d", &sz);
if(u->ch[0]) continue;
u->ch[0] = newnode(sz, u);
}
if(op == 4) {
scanf("%d", &sz);
if(u->ch[1]) continue;
u->ch[1] = newnode(sz, u);
}
}

bfs();
}

int main()
{
_init();
int _ = 0;
while(scanf("%d", &m) != EOF) {
printf("Case #%d: ", ++_);
init();
work();
}

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