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