• Codeforces 954H Path Counting 【DP计数】*


    Codeforces 954H Path Counting


    LINK


    题目大意:给你一棵n层的树,第i层的每个节点有a[i]个儿子节点,然后问你树上的简单路径中长度在1~n*2-2之间的每个有多少条


    因为直接计算过每个节点的路径并不好算
    所以可以算一算从每个节点出发的路径的个数
    f[i][j]表示对于在i层的1个节点,向下走行走j步的方案数
    g[i][j]表示对于在i层的1个节点,第一步向上行走共走j步的方案数

    然后DP式子比较显然
    f[i][j]=a[i]∗f[i+1][j−1]
    g[i][j]=g[i−1][j−1]+[2≤j]∗f[i][j−2]
    然后这样每条路径会在计算的时候被计算两次,所以乘上2的逆元就好了

    但是这样会MLE,就很完蛋

    然后我们发现g式子DP的时候f只会用到i相等,j比他小的
    又因为g的DP式子中是i从小到大来转移的
    所以直接在f上进行修改,i从小到大,j从大到小,然后就不会卡空间了

    也可以滚动,不过要处理一堆东西,懒得写


     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 5010
     4 #define Mod 1000000007
     5 #define inv2 500000004
     6 int f[N][N<<1];
     7 int n,a[N],s[N];
     8 int ans[N<<1]={0};
     9 int add(int a,int b){return (a+b)%Mod;}
    10 int mul(int a,int b){return 1ll*a*b%Mod;}
    11 int main(){
    12     scanf("%d",&n);
    13     for(int i=1;i<n;i++)scanf("%d",&a[i]);
    14     s[1]=1;for(int i=2;i<=n;i++)s[i]=mul(s[i-1],a[i-1]);
    15     for(int i=1;i<=n;i++)f[i][0]=1;
    16     for(int i=n-1;i>=1;i--)
    17         for(int k=1;k<=n-1;k++){
    18             f[i][k]=mul(a[i],f[i+1][k-1]);
    19             ans[k]=add(ans[k],mul(s[i],f[i][k]));
    20         }
    21     for(int i=1;i<=n;i++)f[1][i]=0;
    22     for(int i=2;i<=n;i++)
    23         for(int k=n*2-2;k>=1;k--){
    24             f[i][k]=f[i-1][k-1];
    25             if(k>=2)f[i][k]=add(f[i][k],mul(a[i-1]-1,f[i][k-2]));
    26             ans[k]=add(ans[k],mul(s[i],f[i][k]));
    27         }
    28     for(int i=1;i<=n*2-2;i++)printf("%d ",mul(ans[i],inv2));
    29     return 0;
    30 }
  • 相关阅读:
    转 W P 代码淆混
    Flash网页游戏辅助工具制作简析
    Flash Player安全沙漏规则
    用loader.loadbytes直接load bitmapdata.getpixels产生的bytearray
    游戏及开发人员的认识
    一犯人在执行死刑前三天供出祖传治癌奇方(转)
    AIR教程列表
    养生名言 (春、夏、秋、冬。)
    十天学会单片机和C语言编程
    UI设计规范收藏
  • 原文地址:https://www.cnblogs.com/dream-maker-yk/p/9676267.html
Copyright © 2020-2023  润新知