51nod-1556 计算(默慈金数)

来源:互联网 发布:图像锐化算法有哪些 编辑:程序博客网 时间:2024/05/16 12:04

原题链接

1556 计算
基准时间限制:1 秒 空间限制:524288 KB 分值: 80 难度:5级算法题
 收藏
 关注
有一个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 1000000007using 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;}

0 0
原创粉丝点击