czy的后宫——矩阵快速幂优化DP

Posted lfri

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了czy的后宫——矩阵快速幂优化DP相关的知识,希望对你有一定的参考价值。

题意

有 n 个位置排成一行,可以放 m 种妹子。每个位置可以放也可以不放,规定某些妹子不能相邻,求方案数。

分析

技术图片

 

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

ll qmul(ll x,ll y,ll p)        //快速乘
    x%=p;
    y%=p;
    ll ans=0;
    while(y)
        if(y&1)
            ans+=x;
            if(ans>=p) ans-=p;  //这样写不能有负数
        
        x<<=1;
        if(x>=p) x-=p;
        y>>=1;
    
    return ans;


struct Mat
    int r,c;
    ll m[110][110];
    Mat()
        memset(m,0,sizeof(m));
    
;

Mat mmul(Mat x,Mat y,ll p)
    Mat ans;
    ans.r=x.r;
    ans.c=y.c;
    for(int i=0;i<x.r;i++)
        for(int k=0;k<x.c;k++)
            for(int j=0;j<y.c;j++)
                ans.m[i][j]+=qmul(x.m[i][k],y.m[k][j],p);
                if(ans.m[i][j]>=p) ans.m[i][j]-=p;
            
    return ans;

Mat mpow(Mat x,ll y,ll p)
    Mat ans;
    ans.r=x.r;
    ans.c=x.c;
    for(int i=0;i<ans.c;i++) ans.m[i][i]=1;
    while(y)
        if(y&1) ans=mmul(ans,x,p);
        x=mmul(x,x,p);
        y>>=1;
    
    return ans;


const ll mod = 1000000007;
Mat T, A;
int n, m;
char s[110];


int main()
    scanf("%d%d", &n, &m);
    T.r = T.c = m+1;
    for(int i = 0;i < m;i++)
    
        scanf("%s", s);
        for(int j = 0;j < m;j++)
            T.m[i][j] = 1- (s[j] - 0);
        T.m[i][m] =  1;
    
    for(int i = 0;i <= m;i++)  T.m[m][i] = 1;   //补充一类”空妹子“

    T = mpow(T, n-1, mod);
    A.r = 1, A.c = m+1;
    for(int i = 0;i <= m;i++)  A.m[0][i] = 1;
    A = mmul(A, T, mod);
    ll ans = 0;
    for(int i = 0;i <= m;i++)  ans = (ans + A.m[0][i]) % mod;
    printf("%lld\\n", ans);

    return 0;

没处交题,只能找别人题解的代码对拍,应该没错吧??

 

 

 

参考链接:https://blog.csdn.net/FSAHFGSADHSAKNDAS/article/details/52745912

 

以上是关于czy的后宫——矩阵快速幂优化DP的主要内容,如果未能解决你的问题,请参考以下文章

CodeForces621E 快速矩阵幂优化dp

矩阵快速幂 优化dp 模板

Magic Gems(矩阵快速幂优化dp)

排队 矩阵快速幂优化dp

hdu 5564 Clarke and digits 矩阵快速幂优化数位dp

AtCoder abc256全题解(区间合并模板矩阵快速幂优化dp线段树……)