• hiho一下 第四十二周


    题目1 : 骨牌覆盖问题·二

    时间限制:10000ms
    单点时限:1000ms
    内存限制:256MB

    描述

    上一周我们研究了2xN的骨牌问题,这一周我们不妨加大一下难度,研究一下3xN的骨牌问题?
    所以我们的题目是:对于3xN的棋盘,使用1x2的骨牌去覆盖一共有多少种不同的覆盖方法呢?
    首先我们可以肯定,奇数长度一定是没有办法覆盖的;对于偶数长度,比如2,4,我们有下面几种覆盖方式:

    提示:3xN骨牌覆盖

    输入

    第1行:1个整数N。表示棋盘长度。1≤N≤100,000,000

    输出

    第1行:1个整数,表示覆盖方案数 MOD 12357

    样例输入
    62247088
    样例输出
    4037

    题目画错了,n=4的解是11,图中有两个相同的图案。
    解法:n等于奇数结果是0,这里求偶数间的递推公式,i表示第i个偶数;
    观测n=4的图可以发现a[i+1]=3*a[i]+2*a[i-1]+2*a[i-2]+.....+a[0];
    由此可以得到a[i+1]=4*a[i]-a[i-1];初值a[0]=1,a[1]=3;
    再使用矩阵的n方的的加速算法可得解;O(log(n)).
    #include <cstdio>
    #include <cstring>
    int n;
    const int mod = 12357;
    long long a[2][2],b[2][2],c[2][2];
    int main(){
       a[0][0]=4;a[0][1]=12356;a[1][0]=1;
       b[0][0]=1;b[1][1]=1;
       scanf("%d",&n);
       if(n&1){
           printf("0\n");
           return 0;
       }
       n>>=1;
       while(n){
           if(n&1){
               memcpy(c,b,sizeof(b));
               b[0][0]=(c[0][0]*a[0][0]+c[0][1]*a[1][0])%mod;
               b[0][1]=(c[0][0]*a[0][1]+c[0][1]*a[1][1])%mod;
               b[1][1]=(c[1][0]*a[0][1]+c[1][1]*a[1][1])%mod;
               b[1][0]=(c[1][0]*a[0][0]+c[1][1]*a[1][0])%mod;
           }
           memcpy(c,a,sizeof(a));
           a[0][0]=(c[0][0]*c[0][0]+c[0][1]*c[1][0])%mod;
           a[0][1]=(c[0][0]*c[0][1]+c[0][1]*c[1][1])%mod;
           a[1][1]=(c[1][0]*c[0][1]+c[1][1]*c[1][1])%mod;
           a[1][0]=(c[1][0]*c[0][0]+c[1][1]*c[1][0])%mod;
           n>>=1;
       }
       printf("%d\n",(b[1][0]*3+b[1][1])%mod);
       return 0;
    }
  • 相关阅读:
    洛谷P1218 [USACO1.5]特殊的质数肋骨 Superprime Rib
    洛谷 P1062 数列
    洛谷 P2822 组合数问题
    HDU 6112 今夕何夕
    poj 2115 C Looooops
    HDU 6092 Rikka with Subset
    poj 2720 Last Digits
    poj 1254 Hansel and Grethel
    poj 1222 EXTENDED LIGHTS OUT
    poj 2459 Sumsets
  • 原文地址:https://www.cnblogs.com/zhjou/p/4438156.html
Copyright © 2020-2023  润新知