[除草][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;
}
原文地址:https://www.cnblogs.com/hsuppr/p/3103739.html