AGC013D Piling Up

Link
(f_{i,j})表示进行(i)次操作,还剩(j)个黑球的方案数。
转移为(f_{i,j}=f_{i-1,j-1}+2f_{i-1,j}+f_{i-1,j+1})
这是个经典的格路问题,为了防止算重我们需要强制每条路径都经过(j=0)的点。
直接减去((n-1,m))的子问题即可。

#include<cstdio>
#include<algorithm>
using u32=unsigned int;
const int P=1000000007;
u32 f[2][3007];
int cal(int m,int n)
{
    int now=0,sum=0;
    std::fill(f[0]+1,f[0]+m+1,1),f[0][0]=f[0][m+1]=f[1][0]=f[1][m+1]=0;
    for(int i=0;i<n;++i,now^=1) for(int j=1;j<=m;++j) f[!now][j]=(f[now][j-1]+2*f[now][j]+f[now][j+1])%P;
    for(int i=1;i<=m;++i) (sum+=f[now][i])%=P;
    return sum;
}
int main()
{
    int n,m;scanf("%d%d",&n,&m);
    printf("%d",4ll*(cal(n,m-1)-cal(n-1,m-1)+P)%P);
}
原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12695818.html