• cf954H


    挖我自闭了这是什么东西啊。

    给出一棵深度为 n 的树,其中深度为 i 的节点有 a_i 个儿子。问树上的简单路径中长度在 1sim2n-2 之间的每个有多少条。

    f_{i,j} 表示对于在 i 层的 1 个节点,向下走 j 步的方案数

    g_{i,j} 表示对于在 i 层的 1 个节点,向上走 j 步的方案数

    然后我们可以得到这样的递推式。

     f[i][j]=a[i]*f[i+1][j-1]);
    g[i][j]=(j>=2)*(a[i-1]-1)*f[i][j-2]+g[i-1][j-1]);
    显然对于一条路径会算两次。所以最终答案除以 2
     即可。
    你以为这就完了?
    下面才是自闭的开始。
    256M大概能开6e7?记不清了。。。所以我们只能开一个[5000][9999]这样纸的数组,然后滚来滚去滚来滚去。
    ac代码:
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int mod = 1e9+7;
     5 int n;
     6 int a[5001],c[5005];
     7 int f[5001][9999],ans[9999];
     8 int main(){
     9     ios::sync_with_stdio(false);
    10     cin>>n;c[0]=1;
    11     for(int i=1;i<n;i++)cin>>a[i];
    12     for(int i=1;i<=n;i++)c[i]=1ll*a[i]*c[i-1]%mod;
    13     for(int i=n;i>=1;i--){
    14         f[i][0]=1;
    15         for(int j=1;j<=n-i;j++){
    16             f[i][j]=(1ll*a[i]*f[i+1][j-1])%mod;
    17             ans[j]=(1ll*f[i][j]*c[i-1]+ans[j])%mod;
    18         }
    19     }
    20     for(int i=1;i<=n;i++){
    21         for(int j=2*n-2;j>=1;j--){
    22             f[i][j]=f[i-1][j-1];
    23             if(i>1&&j>1)
    24                 f[i][j]=(1ll*(a[i-1]-1)*f[i][j-2]+f[i][j])%mod;
    25             ans[j]=(1ll*f[i][j]*c[i-1]+ans[j])%mod;
    26         }
    27     }
    28     for(int i=1;i<=2*n-2;i++){
    29         cout<<(mod+1ll)*ans[i]/2%mod<<' ';
    30     }
    31 }
    View Code

    MLE ON TEST 01 代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int mod = 1e9+7;
     5 int n;
     6 int a[5001];
     7 int f[5001][5001],g[5001][9999];
     8 int main(){
     9     ios::sync_with_stdio(false);
    10     cin>>n;a[0]=1;
    11     for(int i=1;i<n;i++)cin>>a[i];
    12     for(int i=1;i<=n;i++)
    13        f[i][1]=a[i],f[i][0]=1;
    14     for(int i=2;i<=n;i++)
    15         g[i][1]=1,g[i][0]=1;
    16     for(int i=n-1;i>=1;i--){
    17         for(int j=2;j<=n-i;j++){
    18             f[i][j]=(1ll*a[i]*f[i+1][j-1])%mod;
    19         }
    20     }
    21     for(int i=2;i<=n;i++){
    22         for(int j=2;j<=2*n-2;j++){
    23             g[i][j]=(1ll*(j>=2)*(a[i-1]-1)*f[i][j-2]+g[i-1][j-1])%mod;
    24         }
    25     }
    26     for(int i=1;i<=n;i++)a[i]=1ll*a[i]*a[i-1]%mod;
    27     for(int i=1;i<=2*n-2;i++){
    28         ll sum = 0;
    29         for(int j=1;j<=n;j++){
    30             sum=(sum+1ll*a[j-1]*(f[j][i]+g[j][i])%mod)%mod;
    31         }
    32         cout<<sum/2<<' ';
    33     }
    34 }
    View Code
     
  • 相关阅读:
    用户需求报告
    结队开发项目——七巧板NABC需求分析
    梦断代码读书笔记3
    课堂练习之环形二维数组
    结对开发之求最大子数组的溢出问题
    《代码之美》第二章读后感(一)
    软件工程项目冲刺阶段二:第五天
    软件工程项目冲刺阶段二:第四天(06-06)
    软件工程项目冲刺阶段二:第三天
    课程评价
  • 原文地址:https://www.cnblogs.com/MXang/p/10220686.html
Copyright © 2020-2023  润新知