递推求值

Covering

Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 481    Accepted Submission(s): 226


Problem Description
Bob's school has a big playground, boys and girls always play games here after school.

To protect boys and girls from getting hurt when playing happily on the playground, rich boy Bob decided to cover the playground using his carpets.

Meanwhile, Bob is a mean boy, so he acquired that his carpets can not overlap one cell twice or more.

He has infinite carpets with sizes of  1×2  and  2×1 , and the size of the playground is  4×n .

Can you tell Bob the total number of schemes where the carpets can cover the playground completely without overlapping?
 

Input
There are no more than 5000 test cases. 

Each test case only contains one positive integer n in a line.

1n1018
 

Output
For each test cases, output the answer mod 1000000007 in a line.
 

Sample Input
  
  
1 2
 

Sample Output
  
  
1 5
 

Source
根据转移的状态列出来式子,可以把无用的状态去掉,注意式子一定不要漏掉,漏掉的话就gg,比直接推数据不知道高到哪里去了呢。
代码:
#include<stdio.h>
#include<string.h>
#define mod 1000000007
#define N 6
typedef long long LL;
struct Matrix
{
    LL mat[N][N];
};

Matrix unit_matrix =
{
    1, 0, 0,0,0,0,
    0, 1, 0,0,0,0,
    0, 0, 1,0,0,0,
    0, 0, 0,1,0,0,
    0, 0, 0,0,1,0,
    0, 0, 0,0,0,1
}; //单位矩阵

Matrix mul(Matrix a, Matrix b) //矩阵相乘
{
    Matrix res;
    for(int i = 0; i < N; i++)
        for(int j = 0; j < N; j++)
        {
            res.mat[i][j] = 0;
            for(int k = 0; k < N; k++)
            {
                res.mat[i][j] += a.mat[i][k] * b.mat[k][j];
                res.mat[i][j] %= mod;
            }
        }
    return res;
}

Matrix pow_matrix(Matrix a, LL n)  //矩阵快速幂
{
    Matrix res = unit_matrix;
    while(n != 0)
    {
        if(n & 1)
            res = mul(res, a);
        a = mul(a, a);
        n >>= 1;
    }
    return res;
}

int main()
{
    LL n;
    Matrix tmp, arr;

    while(scanf("%I64d",&n)!=EOF)
    {
//        scanf("%lld%lld%lld%lld%lld%lld",&f1, &f2, &a, &b, &c, &n);
        memset(arr.mat, 0, sizeof(arr.mat));
        memset(tmp.mat, 0, sizeof(tmp.mat));
        arr.mat[0][0] = 1;
        arr.mat[1][0] = 1;
        arr.mat[2][0] = 0;
        arr.mat[3][0] = 1;
        arr.mat[4][0] = 1;
        arr.mat[5][0] = 1;
        tmp.mat[0][5] = 1,tmp.mat[0][0]=1,tmp.mat[0][4] = 1,tmp.mat[0][1]=1,tmp.mat[0][3]=1;
        tmp.mat[1][0] = 1,tmp.mat[1][4]=1;
        tmp.mat[2][3]=1;
        tmp.mat[3][0]=1,tmp.mat[3][2]=1;
        tmp.mat[4][0]=1,tmp.mat[4][1]=1;
        tmp.mat[5][0]=1;
        tmp.mat[1][1] = tmp.mat[1][2] = tmp.mat[2][0] = tmp.mat[2][1] = 0;
        Matrix p = pow_matrix(tmp, n-1);
        p = mul(p, arr);
        LL ans = (p.mat[0][0] ) % mod;
        printf("%I64d\n",ans);
    }
}

动态规划是一种常用的解决问题的算法,其核心思想是将一个复杂的问题分解为多个子问题进行求解,通过保存之前的状态来减少计算量,从而达到优化算法的目的。动态规划有两种求解方式,一种是递推求解法,另一种是记忆化搜索法。 递推求解法是指从小到大依次计算子问题的解,逐步推导出整个问题的最优解。这种方法需要定义一个状态转移方程,通过状态转移方程来求解问题。具体步骤如下: 1. 定义状态:将原问题拆分成若干个子问题,根据子问题定义状态。 2. 定义状态转移方程:根据子问题之间的关系,定义状态转移方程。 3. 确定边界条件:确定最小的子问题的解。 4. 递推求解:根据状态转移方程从边界条件出发,逐步计算得到整个问题的解。 下面以斐波那契数列为例,介绍动态规划递推求解法的具体实现过程。 假设要求斐波那契数列的第n项的,斐波那契数列的定义如下: f(0) = 0 f(1) = 1 f(n) = f(n-1) + f(n-2) (n>=2) 1. 定义状态 将原问题拆分成若干个子问题,根据子问题定义状态。对于斐波那契数列,我们可以将其拆分成n-1和n-2两个子问题,然后定义状态f(n)表示斐波那契数列的第n项的。 2. 定义状态转移方程 根据子问题之间的关系,定义状态转移方程。对于斐波那契数列,由于f(n)依赖于f(n-1)和f(n-2),因此可以得到状态转移方程: f(n) = f(n-1) + f(n-2) 3. 确定边界条件 确定最小的子问题的解。对于斐波那契数列,边界条件为f(0)=0和f(1)=1。 4. 递推求解 根据状态转移方程从边界条件出发,逐步计算得到整个问题的解。具体实现过程如下: ```python def fibonacci(n): if n == 0: return 0 elif n == 1: return 1 else: f = * (n+1) f = 0 f = 1 for i in range(2, n+1): f[i] = f[i-1] + f[i-2] return f[n] ``` 以上就是动态规划递推求解法的具体实现过程。如果您有任何疑问或者其他相关问题,请随时提出。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值