POJ 3420 (矩阵二分幂优化,状压DP)

来源:互联网 发布:科比2016数据 编辑:程序博客网 时间:2024/05/08 22:31

由于n<=10^9 ,显然线性推是不可能的。假如,当n很小的时候,同2663题,我们可以用dp的方式做。那么,我们可以打表,找出小数据的一些值,找出规律。f[n]=f[n-1]+5*f[n-2]+f[n-3]-f[n-4]。

以上式子是线性的关系,显然可以构造矩阵。

#include<iostream>#include<iostream>#include<string>#include<stdio.h>#include<string.h>#include<vector>#include<math.h>#include<queue>#include<map>#include<set>#include<algorithm>using namespace std;#define MAXN 16#define LL __int64const int INF=0x3f7f7f7f;int mod;class Matrix{public:    int a[MAXN][MAXN];    Matrix()    {        memset(a,0,sizeof(a));    }    Matrix(int x)    {        memset(a,0,sizeof(a));        if(x==1)        for(int i=0;i<MAXN;i++)            a[i][i]=1;    }    Matrix operator +(const Matrix &b)const    {        Matrix temp;        for(int  i=1;i<MAXN;i++)        {            for(int j=1;j<MAXN;j++)            {                temp.a[i][j]=a[i][j]+b.a[i][j];            }        }        return temp;    }     Matrix operator -(const Matrix &b)const     {        Matrix temp;        for(int  i=1;i<MAXN;i++)        {            for(int j=1;j<MAXN;j++)            {                temp.a[i][j]=a[i][j]-b.a[i][j];            }        }        return temp;     }     Matrix operator *(const Matrix &b)const     {        Matrix temp;        for(int  i=1;i<MAXN;i++)        {            for(int j=1;j<MAXN;j++)            {                for(int k=1;k<MAXN;k++)                {                    temp.a[i][j]+=(a[i][k]*b.a[k][j])%mod;                    while(temp.a[i][j]<0)                        temp.a[i][j]+=mod;                    temp.a[i][j]%=mod;                }            }        }        return temp;     }     Matrix mat_pow(Matrix x,int n)     {         Matrix ans(1);         while(n)         {             if(n%2)                ans=ans*x;             x=x*x;             n>>=1;         }         return ans;     }};Matrix temp;Matrix ans;int main(){    int n,i,j;    while(scanf("%d%d",&n,&mod)!=EOF)    {        if(n==0&&mod==0)break;        if(n==1)        {            printf("%d\n",1%mod);            continue;        }        if(n==2)        {            printf("%d\n",5%mod);            continue;        }        if(n==3)        {            printf("%d\n",11%mod);            continue;        }        if(n==4)        {            printf("%d\n",36%mod);            continue;        }        temp=temp.mat_pow(temp,n-4);        ans=temp*ans;        printf("%d\n",ans.a[1][1]%mod);    }    return 0;}


0 0
原创粉丝点击