zoukankan      html  css  js  c++  java
  • 递推dp 超级树

    这里写图片描述
    设f[i][j],i表示i-超级树,j表示树上同时存在j条路径且无重复的点。
    首先得解释明白数组含义。。。
    第二维的目的很单纯:把路径合并时不会走重复的点,不会走重复的边。
    那么说一下转移,
    设sum=f[i-1][l]*f[i-1]*r;

    1. 什么也不往上加 f[i][l+r]+=sum;
    2. 只把根节点自己加上去 f[i][l+r+1]+=sum
    3. 把根节点和两棵子树中某一条路径连起来 f[i][l+r]+=sum*2*(l+r){要考虑双向,左右子树各自枚举}
    4. 把根节点和一左一右两条路径连起来 f[i][l+r-1]+=sum*2*l*r
    5. 把根节点和两个左(或右)子树路径连起来 f[i][l+r-1]+=sum*2*(l*(l-1)+r*(r-1))

      转移大概就是这样了,那么来考虑初始化和输出,
      初始化:f[1][0]=f[1][1]=1;
      输出:f[k][1],树上只有一条路径且自己上面无重复的点的总方案数。
      那么再来想,f[k][1]只能有f[k-1][2]转移而来。依次类推,第二维只需要存最大到k个的方案数就行了(记得和总节点数量比一下,防TLE,博主死于此)
      O(k^3)

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define ll long long
    using namespace std;
    ll n,mod,f[305][305];
    int main()
    {
    //  freopen("tree.in","r",stdin);
    //  freopen("tree.out","w",stdout);
        scanf("%lld%lld",&n,&mod);
        f[1][0]=f[1][1]=1;
        for(int i=2;i<=n;i++)
        {
            ll k=n-i+2;
            if(i<=9)k=min(k,(ll)1<<(i-1));
            for(ll l=0;l<=k;l++)
                for(ll r=0;r<=k;r++)
                    if(l+r<=n)
                    {
                        ll h=f[i-1][l]*f[i-1][r]%mod;
                        f[i][l+r]+=h;                               if(f[i][l+r]>=mod)f[i][l+r]-=mod;
                        f[i][l+r+1]+=h;                             if(f[i][l+r+1]>=mod)f[i][l+r+1]-=mod;
                        f[i][l+r]+=2*h*(l+r)%mod;                    if(f[i][l+r]>=mod)f[i][l+r]-=mod;
                        f[i][l+r-1]+=2*h*(l*r%mod)%mod;              if(f[i][l+r-1]>=mod)f[i][l+r-1]-=mod;
                        f[i][l+r-1]+=h*(l*(l-1)%mod+r*(r-1)%mod)%mod;if(f[i][l+r-1]>=mod)f[i][l+r-1]-=mod;
                    }
        }
        cout<<f[n][1]%mod;
    }
  • 相关阅读:
    分梨
    18岁生日
    马的移动
    摆积木
    杭电2093考试排名
    栈的应用——四则运算表达式求值
    用指针实现对二维数组元素的访问
    用多种方法访问字符数组元素
    fread()函数和fwrite()函数进行文件操作
    hdu-1431 素数回文
  • 原文地址:https://www.cnblogs.com/QTY2001/p/7632677.html
Copyright © 2011-2022 走看看