有一个1*n的矩阵 固定第一个数为1 其他填正整数 且相邻数的差不能超过1 求方案数%1e9+7的结果
Input
一个数n 表示1*n的矩阵(n<=10^6)
Output
一个数 表示方案数%1e9+7的结果
Input示例
3
Output示例
5
默慈金数的推导公式
在一个网格上,若限定每步只能向右移动一格,可以右上,右下,横向,向右,并禁止移动到以下的地方,则以这种走法移动步从到的可能形成的路径的总数为的默慈金数。
这道题是这个例子的变型,从(0, 0)走到(n,x) x >= 0,仔细思考会发现T[n] = 3*T[n-1] - M[n-1].
因为走到横坐标为n-1还可以往三个方向走,除了(n-1, 0)只能往两个方向走.
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#define maxn 1000005
#define MOD 1000000007
using namespace std;
typedef long long ll;
ll d[maxn], p[maxn];
ll solve(ll p){
ll ans = 1, m = MOD - 2;
while(m){
if(m&1)(ans *= p) %= MOD;
(p *= p) %= MOD;
m >>= 1;
}
return ans;
}
int main(){
d[1] = 1;
d[2] = 2;
p[1] = 2;
p[2] = 5;
for(int i = 3; i <= 1000000; i++){
int j = i - 1;
d[i] = ((2 * j + 3) * d[j] % MOD+ 3 * j * d[j-1] % MOD) % MOD * solve((ll)j + 3);
d[i] %= MOD;
p[i] = ((3 * p[i-1] - d[i-1]) % MOD + MOD) % MOD;
}
int n;
while(scanf("%d", &n) == 1){
printf("%I64d\n", p[n-1]);
}
return 0;
}