codility上的问题 (22)

问题描述: 用1 * 1, 1 * 2的矩形覆盖一个n行m列的矩形,问有多少种方法。

数据范围 : n [1..10^6],  m [ 1..7]

要求复杂度: 时间  O(log(n) * 8 ^m))  空间  O(4^m)

分析:这个题跟之前那个木块砌墙问题一样…… 稍作修改即可,又是矩阵乘法。

http://blog.csdn.net/caopengcs/article/details/9928061

代码:

 

// you can also use includes, for example:

// #include <algorithm>



#include <vector>





vector<vector<int> > a;



const int MOD =  10000007;



int add(int x,int y) {

    return ((x += y) >= MOD)?(x - MOD):x;

}



int mul(long long x,long long y) {

    return x * y % MOD;

}



vector<vector<int> >  mulmatrix(vector<vector<int> > &a,vector<vector<int> > &b) {

vector<vector<int> > c;

int n = a.size(), i ,j, k;

    c.resize(n);

    for (i = 0; i < n; ++i) {

    	c[i].resize(n , 0);

        for (j = 0; j < n; ++j) {

        	for (k = 0; k < n; ++k) {

            	c[i][j] = add(c[i][j], mul(a[i][k],b[k][j]));

            }

        }

    }

  	return c;

}

        



void count(int col, int n, int last, int now) {

    if (col >= n) {

        ++a[last][now];

        return;

    }

   	count(col + 1, n, last, now);

    if (((last & (1 << col)) == 0) && (col + 1 < n) && ((last & (1 << (col + 1))) == 0)) {

        count(col + 2, n, last, now | (3 << col));

    }

}

    



int solution(int N, int M) {

    // write your code here...

int i,total = 1 << M;

vector<vector<int> > r;

    a.resize(total);

    r.resize(total);

    for (i = 0; i < total; ++i) {

        a[i].resize(total, 0);

        count(0, M, i, 0);

        r[i].resize(total, 0);

        r[i][i] = 1;

    }

    for (; N ; N >>= 1) {

        if (N & 1) {

            r = mulmatrix(r, a);

        }

        a = mulmatrix(a, a);

    }

    

    return r[0][0];

    

        

}


 

 

你可能感兴趣的:(it)