zoukankan      html  css  js  c++  java
  • An unavoidable detour for home CodeForces

    大意: 给定一棵树每个点的度数, 求所有满足条件的树的个数

    • 每个点到$1$的最短路唯一
    • 假设$l_i$为点$i$到$1$的最短距离, 那么$l_ige l_{i-1}$
    • 每个点度数范围$2le d_i le 3$

    $dp_{i,a1,a2,b1,b2}$表示的是前$i$个点, 上一层$a_1$个度数为$1$的,$a_2$个度数为$2$的

    当前层$b_1$个度数为$1$的, $b_2$个度数为$2$的方案.

    暴力$O(n^5)$转移即可

    好像有一个$O(n^3)$的做法 链接

    #include <iostream>
    #include <sstream>
    #include <algorithm>
    #include <cstdio>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    #include <cstring>
    #include <bitset>
    #include <functional>
    #include <random>
    #define REP(i,a,n) for(int i=a;i<=n;++i)
    #define PER(i,a,n) for(int i=n;i>=a;--i)
    #define hr putchar(10)
    #define pb push_back
    #define lc (o<<1)
    #define rc (lc|1)
    #define mid ((l+r)>>1)
    #define ls lc,l,mid
    #define rs rc,mid+1,r
    #define x first
    #define y second
    #define io std::ios::sync_with_stdio(false)
    #define endl '
    '
    #define DB(a) ({REP(__i,1,n) cout<<a[__i]<<',';hr;})
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pii;
    const int P = 1e9+7, INF = 0x3f3f3f3f;
    ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
    ll qpow(ll a,ll n) {ll r=1%P;for (a%=P;n;a=a*a%P,n>>=1)if(n&1)r=r*a%P;return r;}
    ll inv(ll x){return x<=1?1:inv(P%x)*(P-P/x)%P;}
    inline int rd() {int x=0;char p=getchar();while(p<'0'||p>'9')p=getchar();while(p>='0'&&p<='9')x=x*10+p-'0',p=getchar();return x;}
    //head
     
     
     
    const int N = 55;
    int n, a[N], dp[2][N][N][N][N];
    void add(int &a, ll b) {a=(a+b)%P;}
    ll C(int x) {return (ll)x*(x-1)/2;}
     
    int main() {
        scanf("%d", &n);
        REP(i,1,n) scanf("%d", a+i);
        int cur = 0;
        dp[cur][a[1]==2][a[1]==3][a[2]==2][a[2]==3]=1;
        REP(i,3,n) {
            cur ^= 1;
            memset(dp[cur],0,sizeof dp[0]);
            PER(a1,0,i-1) PER(a2,0,i-1-a1) PER(b1,0,i-1-a1-a2) PER(b2,0,i-1-b1-a2-a1) {
                ll r = dp[!cur][a1][a2][b1][b2];
                if (!r) continue;
                if (a[i]==2) {
                    //连向当前层
                    if (a1) add(dp[cur][a1-1][a2][b1+1][b2],a1*r);
                    if (a2) add(dp[cur][a1+1][a2-1][b1+1][b2],a2*r);
                    if (a1&&b1) add(dp[cur][a1-1][a2][b1-1][b2],a1*b1*r);
                    if (a1&&b2) add(dp[cur][a1-1][a2][b1+1][b2-1],a1*b2*r);
                    if (a2&&b1) add(dp[cur][a1+1][a2-1][b1-1][b2],a2*b1*r);
                    if (a2&&b2) add(dp[cur][a1+1][a2-1][b1+1][b2-1],a2*b2*r);
                    //连向下一层
                    if (!a1&&!a2) {
                        if (b1) add(dp[cur][b1-1][b2][1][0],b1*r);
                        if (b2) add(dp[cur][b1+1][b2-1][1][0],b2*r);
                    }
                }
                else {
                    //连向当前层
                    if (a1) add(dp[cur][a1-1][a2][b1][b2+1],a1*r);
                    if (a2) add(dp[cur][a1+1][a2-1][b1][b2+1],a2*r);
                    if (a1&&b1) add(dp[cur][a1-1][a2][b1][b2],a1*b1*r);
                    if (a1&&b2) add(dp[cur][a1-1][a2][b1+2][b2-1],a1*b2*r);
                    if (a2&&b1) add(dp[cur][a1+1][a2-1][b1][b2],a2*b1*r);
                    if (a2&&b2) add(dp[cur][a1+1][a2-1][b1+2][b2-1],a2*b2*r);
                    if (a1&&b1&&b2) add(dp[cur][a1-1][a2][b1][b2-1],a1*b1*b2*r);
                    if (a2&&b1&&b2) add(dp[cur][a1+1][a2-1][b1][b2-1],a2*b1*b2*r);
                    if (b1>=2&&a1) add(dp[cur][a1-1][a2][b1-2][b2],C(b1)*a1*r);
                    if (b1>=2&&a2) add(dp[cur][a1+1][a2-1][b1-2][b2],C(b1)*a2*r);
                    if (b2>=2&&a1) add(dp[cur][a1-1][a2][b1+2][b2-2],C(b2)*a1*r);
                    if (b2>=2&&a2) add(dp[cur][a1+1][a2-1][b1+2][b2-2],C(b2)*a2*r);
                    //连向下一层
                    if (!a1&&!a2) {
                        if (b1) add(dp[cur][b1-1][b2][0][1],b1*r);
                        if (b2) add(dp[cur][b1+1][b2-1][0][1],b2*r);
                    }
                }
            }
        }
        printf("%d
    ",dp[cur][0][0][0][0]);
    }
    
  • 相关阅读:
    POJ 2923 Relocation (状态压缩,01背包)
    HDU 2126 Buy the souvenirs (01背包,输出方案数)
    hdu 2639 Bone Collector II (01背包,求第k优解)
    UVA 562 Dividing coins (01背包)
    POJ 3437 Tree Grafting
    Light OJ 1095 Arrange the Numbers(容斥)
    BZOJ 1560 火星藏宝图(DP)
    POJ 3675 Telescope
    POJ 2986 A Triangle and a Circle
    BZOJ 1040 骑士
  • 原文地址:https://www.cnblogs.com/uid001/p/11608990.html
Copyright © 2011-2022 走看看