Hoj 2930 Perfect Fill II

来源:互联网 发布:春药在淘宝上怎么购买 编辑:程序博客网 时间:2024/05/17 21:48

题目链接:http://acm.hit.edu.cn/hoj/problem/view?id=2930

本题是处理线性递推。

递推式:f[i] = 2*f[i-1] + f[i-3];

求线性递推问题可以转换为矩阵运算:

出任何一个线性递推式的第n项,其对应矩阵的构造方法为:在右上角的(n-1)*(n-1)的小矩阵中的主对角线上填1,矩阵第n行填对应的系数,其它地方都填0。例如,我们可以用下面的矩阵乘法来二分计算f(n) = 4f(n-1) - 3f(n-2) + 2f(n-4)的第k项:


a,b,c,d的顺序为项数的从低到高。

对于本题的递推式,f[i] = 2*f[i-1] + f[i-3];

我们可以构造连乘矩阵:

A= [0 1 0

0 0 1

1 0 2],

B = [f[0]

f[1]

f[2]]

则第n项f[n] = A^(n-2) * B.

另外用到矩阵的快速幂运算,用二分法就行了。

#include <iostream>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include <vector>#include <queue>#include <algorithm>using namespace std;#define max 3struct Matrix{    int data[max][max];};Matrix A,B;int n = 3;int mod = 2010;void init(){    memset(A.data,0,sizeof(A.data));    memset(B.data,0,sizeof(B.data));    A.data[0][1] = 1;    A.data[1][2] = 1;    A.data[2][0] = 1;    A.data[2][2] = 2;    B.data[0][0] = 1;    B.data[1][0] = 1;    B.data[2][0] = 2;}//矩阵相乘Matrix mul(Matrix u,Matrix v){    Matrix t;    for(int i=0;i<n;i++)    {        for(int j=0;j<n;j++)        {            t.data[i][j] = 0;            for(int k=0;k<n;k++)            {                t.data[i][j] += (u.data[i][k] * v.data[k][j])%mod;                t.data[i][j] %= mod;            }        }    }    return t;}//矩阵的幂Matrix power(Matrix matrix,int k){    int k_temp = k;    Matrix result,a;    memset(result.data,0,sizeof(result.data));    for(int i=0;i<n;i++)    {        for(int j=0;j<n;j++)        {            a.data[i][j] = matrix.data[i][j];            if(i == j)            {                result.data[i][j] = 1;            }            //printf("%d ",a.data[i][j]);        }        //printf("\n");    }    while(k_temp)    {        if(k_temp&1)        {            result = mul(result,a);        }        a = mul(a,a);        k_temp = k_temp>>1;    }    return result;}int main(){#ifndef ONLINE_JUDGE    freopen("in.txt","r",stdin);#endif    int num;    init();    while(scanf(" %d",&num)!=EOF)    {        if(num == 1) printf("1\n");        else if(num == 2) printf("2\n");        else        {            Matrix temp = power(A,num - 2);            Matrix fin = mul(temp,B);            printf("%d\n",fin.data[2][0]);        }    }    return 0;}


原创粉丝点击