【51Nod 1556】计算

Description

有一个1*n的矩阵 固定第一个数为1 其他填正整数 且相邻数的差不能超过1 求方案数%1e9+7的结果

Solution

我们观察一下从i推到i+1的数里面,除了是1的数要乘2,其他的都要乘3。
那么现在的问题就是在一个二维平面里面,从(0,0)走到(i,0)可以向上,向下向右走一格,但是只能在第一象限,有多少种走法?
到网上看看了,这个就是默慈金数:

m[i]=m[i1](2i+1)+(3i3)m[i2]i+2

m[1]=1,m[2]=2
打成方便记忆的方式就是:
m[i]=m[i1](2(i1)+3)+m[i2](3(i2)+3)i+2

然后 f[n]=f[n1]3m[i2]

Code

#include
#include
#include
#include
#include
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fod(i,a,b) for(i=a;i>=b;i++)
using namespace std;
typedef long long ll;
const int mo=1e9+7,maxn=1e6+7;
ll i,j,k,l,t,n,m,ans;
ll f[maxn],g[maxn];
ll qsm(ll x,ll y){
    ll z=1;
    for(;y;y/=2,x=x*x%mo)if(y&1)z=z*x%mo;
    return z;
}
int main(){
    scanf("%d",&n);
    f[1]=1,g[1]=1,g[2]=2,f[2]=2;
    fo(i,3,n){
        g[i]=(g[i-1]*(2*i+1)%mo+3*(i-1)*g[i-2]%mo)%mo*qsm(i+2,mo-2)%mo;
        f[i]=f[i-1]*3-g[i-2];
        f[i]=(f[i]%mo+mo)%mo;
    }
    printf("%lld\n",f[n]);
}

你可能感兴趣的:(51Nod,51Nod1556,计算,默慈金数,递推,数论,51Nod,默慈金数)