[除草][HEOI2013]SAO
。。。不好解释
直接上代码:
/**
* Problem:SAO
* Author:Shun Yao
* Time:2013.5.22
* Result:Accepted
* Memo:DP
*/
#include <cstring>
#include <cstdlib>
#include <cstdio>
#define SLL signed long long
#define MOD 1000000007
using namespace std;
const long Maxn = 1005, Maxm = 10005;
long n, siz[Maxn], c[Maxn][Maxn], f[Maxn][Maxn], f1[Maxn][Maxn], pp[Maxn];
char vis[Maxn];
long tot;
class gnode {
public:
long v;
gnode *next;
gnode(long V, gnode *ne):v(V), next(ne) {}
gnode() {}
~gnode() {}
} *g[Maxn], *g1[Maxn], *gg[Maxn], *gg1[Maxn], G[Maxm];
void clear(gnode *&g) {
g = 0;
}
void add(gnode *&g, long V) {
g = &(G[tot++] = gnode(V, g));
}
void dp(long x) {
gnode *e;
long cur, i, j, k;
vis[x] = 1;
siz[x] = 1;
for (e = g[x]; e; e = e->next)
if (!vis[e->v]) {
dp(e->v);
siz[x] += siz[e->v];
add(gg[x], e->v);
}
for (e = g1[x]; e; e = e->next)
if (!vis[e->v]) {
dp(e->v);
siz[x] += siz[e->v];
add(gg1[x], e->v);
}
memset(f[x], 0, sizeof f[x]);
f[x][0] = 1;
cur = 0;
for (e = gg[x]; e; e = e->next) {
for (j = 0; j <= siz[x]; ++j) {
pp[j] = f[x][j];
f[x][j] = 0;
}
cur += siz[e->v];
for (j = 0; j <= siz[e->v]; ++j)
for (k = j + 1; k <= cur; ++k)
f[x][k] = ((SLL)pp[k - j - 1] * (SLL)f[e->v][j] % MOD * (SLL)c[k][j + 1] % MOD * (SLL)c[cur - k][siz[e->v] - j - 1] % MOD + f[x][k]) % MOD;
}
for (e = gg1[x]; e; e = e->next) {
for (j = 0; j <= siz[x]; ++j) {
pp[j] = f[x][j];
f[x][j] = 0;
}
cur += siz[e->v];
for (j = 0; j <= siz[e->v]; ++j)
for (k = j; k <= cur; ++k)
f[x][k] = ((SLL)pp[k - j] * (SLL)f1[e->v][j] % MOD * (SLL)c[k][j] % MOD * (SLL)c[cur - k][siz[e->v] - j] % MOD + f[x][k]) % MOD;
}
for (i = 0; i <= siz[x]; ++i)
f1[x][i] = f[x][i];
for (i = 1; i <= siz[x]; ++i)
f[x][i] = (f[x][i] + f[x][i - 1]) % MOD;
for (i = siz[x] - 1; i >= 0; --i)
f1[x][i] = (f1[x][i] + f1[x][i + 1]) % MOD;
}
int main() {
static long tt, i, j, x, y;
static char ch;
memset(c, 0, sizeof c);
for (i = 0; i < Maxn; ++i) {
c[i][0] = 1;
for (j = 1; j <= i; ++j)
c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % MOD;
}
scanf("%ld", &tt);
while (tt--) {
scanf("%ld", &n);
tot = 0;
for (i = 0; i < n; ++i) {
clear(g[i]);
clear(g1[i]);
clear(gg[i]);
clear(gg1[i]);
}
for (i = 0; i < n - 1; ++i) {
scanf("%ld", &x);
scanf(" %c", &ch);
scanf("%ld", &y);
if (ch == '<') {
add(g[x], y);
add(g1[y], x);
} else {
add(g[y], x);
add(g1[x], y);
}
}
memset(vis, 0, sizeof vis);
memset(siz, 0, sizeof siz);
dp(0);
printf("%ld\n", f[0][n]);
}
return 0;
}
作者:HSUPPR
出处:http://www.cnblogs.com/hsuppr/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出
原文链接,否则保留追究法律责任的权利。

浙公网安备 33010602011771号