codility上的问题 (22)Phi 2012

问题描述: 用1 * 1, 2 * 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];
    
        
}


你可能感兴趣的:(算法,codility)