【状压dp && 矩阵快速幂】 POJ

来源:互联网 发布:linux人 编辑:程序博客网 时间:2024/05/20 06:05

Problem Description

给你一个4×N的矩阵,你可以填1×2的矩阵 or 2×1的矩阵,问你填满有多少种方案,需要取mod。

思路:

poj 2411的基础上加了个矩阵快速幂

#include<cstdio>#include<cstring>using namespace std;struct node{    long long a[16][16];};node c;int n, mod;void dfs(int l, int now, int pre){    if(l > 4) return;    if(l == 4)    {        c.a[pre][now]++;        return ;    }    dfs(l + 2, (now<<2)|3, (pre<<2)|3);    dfs(l + 1, now<<1, (pre<<1)|1);    dfs(l + 1, (now<<1)|1, pre<<1);}node mul(node x, node y)//矩阵相乘{    node ans;    int i, j, k;    for(i = 0; i < 16; i++)    {        for(j = 0; j < 16; j++)        {            ans.a[i][j] = 0;            for(k = 0; k < 16; k++)            {                ans.a[i][j] += x.a[i][k] * y.a[j][k];                ans.a[i][j] %= mod;            }        }    }    return ans;}node sm(node x, int m)//矩阵快速幂{    node ans;    memset(ans.a, 0, sizeof(ans.a));    for(int i = 0; i < 16; i++) ans.a[i][i] = 1;    while(m)    {        if(m & 1) ans = mul(ans, x);        x = mul(x, x);        m = m>>1;    }    return ans;}int main(){    while(~scanf("%d %d", &n, &mod))    {        if(!n && !mod) break;        if(mod == 1) {printf("0\n"); continue;}        memset(c.a, 0, sizeof(c.a));        dfs(0, 0, 0);        node ans = sm(c, n);        printf("%lld\n", ans.a[15][15]);    }    return 0;}
原创粉丝点击