2017-07-20:考试(组合数、杨辉三角)SOJP1796

1.杨辉三角:从上到下为下标由0开始,从从左到右为由上标由0开始

    for (int i=0;i<=4000;i++)
        c[i][0]=c[i][i]=1;
    for (int i=2;i<=4000;i++)
        for (int j=1;j<i;j++){
            c[i][j]=c[i-1][j]+c[i-1][j-1];
            cmod(c[i][j]);
        }

2.前缀和

inline void solve(){    
    n=readin();
    m=readin();
    memset(s,0,sizeof(s));
    for (int i=0;i<=m;i++) s[0][i]=1;
    for (int i=1;i<=n;i++)
        for (int j=0;j<=m;j++){
            now=s[i-1][j];
            cmod(now);
            now=now*c[m+j-1][m-1]%Mod;
            s[i][j]=now;
            if (j) s[i][j]+=s[i][j-1];
            cmod(s[i][j]);
        }
    cout<<s[n][m]<<endl;
}
求前缀和:

将f[i][0]至f[i][j]的和全部存入f[i][j] (f[i][j]就是i行的前缀和),用f[i][j]乘上下一行f[i+1][j] (因为都满足[0···j<=j]),
为了使下一次求i+1行时同样可以使用前缀和,要将f[i+1][0]到f[i+1][j]的和存入f[i+1][j],
由于从f[i+1][0]到f[i+1][j-1]都进行了前缀和处理,在加f[i+1][j]时只需加上f[i+1][j-1]即可
这里写图片描述

组合数:

c[j+m-1][m-1]表示从j+m-1的长度中选择m-1个长度为单位1的切割点的方案数,
剩下长度总和为j,且被分成m段,每段的单位1相加的和,即是这段对应的数的大小,
对于正在求的第i行,长度为m,每一位上的数相加为j的总方案数
将此方案数乘上上一行i-1的总和为从0到j的总方案数,成为一个i*m的矩阵且最后一行的和为j的总方案数
加上最后一行的和为0至j-1的矩阵的总方案数后,s[i][j]就彻底变成一个i*m的矩阵的前缀和

这里写图片描述
上图,m=4,j=9

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值