zoukankan      html  css  js  c++  java
  • BZOJ 3167 [Heoi2013]Sao ——树形DP

    BZOJ4824的强化版。

    改变枚举的方案,使用前缀和进行DP优化。

    然后复杂度就是$O(n^2)$了。

    #include <map>
    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define F(i,j,k) for (ll i=j;i<=k;++i)
    #define D(i,j,k) for (ll i=j;i>=k;--i)
    #define ll long long
    #define mp make_pair
    #define maxn 1050
    const ll md=1000000007;
     
    ll h[maxn<<1],to[maxn<<1],ne[maxn<<1],en=0,n;
    ll siz[maxn],tmp[maxn],w[maxn],lim[maxn];
    ll dp[maxn][maxn],c[maxn][maxn],suf[maxn][maxn],pre[maxn][maxn];
    char s[maxn];
    void add(ll a,ll b,ll c)
    {
        to[en]=b;ne[en]=h[a];w[en]=c;h[a]=en++;
    }
     
    ll C(ll n,ll m)
    {
        if (n<0||m<0) return 0;
        return c[n][m];
    }
     
    void Tree_DP(ll o,ll fa)
    {
        dp[o][1]=1;siz[o]=1;
        for (ll i=h[o];i>=0;i=ne[i])
        if (to[i]!=fa){
            Tree_DP(to[i],o);
            F(j,0,siz[o]+siz[to[i]]+2) tmp[j]=0;
            if (w[i]==1)
            {
                F(j,1,siz[o])
                    if (dp[o][j]) F(_j,j,j+siz[to[i]]-1)
                        tmp[_j]+=(((dp[o][j]*suf[to[i]][_j-j+1])%md*C(_j-1,j-1))%md*C(siz[o]+siz[to[i]]-_j,siz[o]-j))%md,tmp[_j]%=md;
            }
            else
            {
                F(j,1,siz[o])
                    if (dp[o][j]) F(_j,j+1,siz[to[i]]+j)
                        tmp[_j]+=(((dp[o][j]*((suf[to[i]][1]-suf[to[i]][_j-j+1])%md+md))%md*C(_j-1,j-1))%md*C(siz[o]+siz[to[i]]-_j,siz[o]-j))%md,tmp[_j]%=md;
            }
            siz[o]+=siz[to[i]];
            F(j,0,siz[o]) dp[o][j]=(tmp[j]%md+md)%md;
        }
        suf[o][siz[o]]=dp[o][siz[o]];
        D(i,siz[o],1) suf[o][i]=(suf[o][i+1]+dp[o][i])%md;
    }
     
    void Finout()
    {
        freopen("in.txt","r",stdin);
        freopen("wa.txt","w",stdout);
    }
     
    ll t; 
     
    int main()
    {
        scanf("%lld",&t);
        c[1][0]=1;c[1][1]=1;c[0][0]=1;
        F(i,2,maxn-1)
        {
            c[i][0]=1;
            F(j,1,maxn-1) c[i][j]=(c[i-1][j]+c[i-1][j-1])%md;
        }
        while (t--)
        {
            memset(dp,0,sizeof dp);
            memset(suf,0,sizeof suf);
            memset(h,-1,sizeof h);en=0;
            scanf("%lld",&n);
            F(i,2,n)
            {
                ll a,b,c;
                scanf("%lld",&a);
                a++;
                scanf("%s",s);
                scanf("%lld",&b);b++;
                switch(s[0])
                {
                    case '<':c=1;break;
                    case '>':c=-1;break;
                }
                add(a,b,c); add(b,a,-c);
            }
            Tree_DP(1,-1);
            ll ans=0;
            F(i,0,n) ans+=dp[1][i],ans%=md;
            printf("%lld
    ",(ans%md+md)%md);
        }
    }
    

      

  • 相关阅读:
    2021 0309-1 准备工作
    课程总结
    第十四周课程总结&实验报告
    第十三周课程总结
    第十二周课程总结
    第十一周课程总结
    第十周课程总结
    2019春总结作业
    第十二周作业
    第十一周作业
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6738672.html
Copyright © 2011-2022 走看看