• [除草][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;
    }
    
  • 相关阅读:
    POJ-2096-Collecting Bugs(概率DP)
    2019ICPC南京网络赛总结
    LOJ-6285-数列分块入门9
    LOJ-6284-数列分块入门8
    LOJ-6283-数列分块7
    bzoj2049: [Sdoi2008]Cave 洞穴勘测
    bzoj1010: [HNOI2008]玩具装箱toy
    bzoj1597: [Usaco2008 Mar]土地购买
    bzoj1233: [Usaco2009Open]干草堆tower 单调队列优化dp
    bzoj2442&&codevs4654 单调队列优化dp
  • 原文地址:https://www.cnblogs.com/hsuppr/p/3103739.html
Copyright © 2020-2023  润新知