POJ 3734

题目的大意:

给定待粉刷的n个墙砖(排成一行),每一个墙砖能够粉刷的颜色种类为:红、蓝、绿、黄,

问粉刷完成后,红色墙砖和蓝色墙砖都是偶数的粉刷方式有多少种(结果对10007取余).

解题思路:

思路用的是递推.如果粉刷到第i个墙砖时,使用的红色墙砖和蓝色墙砖都是偶数的方案

数有ai,使用的红色和蓝色墙砖一奇一偶的方案数为bi,使用的红色和蓝色墙砖都是奇数的

方案数为ci,那么,我们easy得到以下的递推式:

看到上式,对于学过线代的人来说一定不陌生,我们能够将其写成矩阵的形式,然后会发现该

递推式是等比数列的形式.

对于求取ai,我们可通过计算对应矩阵的幂得知,计算矩阵的幂,利用高速二分幂,

可将时间复杂度降为O(lgn).

解题代码:

#include<vector>
#include<iostream>
#include<algorithm>
#define M 10007
using namespace std;
//矩阵乘法
vector<vector<int> > multi(vector<vector<int> > &A, vector<vector<int> > &B)
{
    vector<vector<int> > C(A.size(), vector<int>(B[0].size()));
    for (unsigned i = 0; i != A.size(); ++i)
        for (unsigned j = 0; j != B[0].size(); ++j)
            for (unsigned k = 0; k != B.size(); ++k)
                C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % M;
    return C;
}
//二分高速幂
vector<vector<int> > power(vector<vector<int> > &A, int n)
{
    vector<vector<int> > B(A.size(), vector<int>(A.size()));
    for (int i = 0; i != A.size(); ++i)
        B[i][i] = 1;
    while (n)
    {
        if (n & 1)
            B = multi(B, A);
        A = multi(A, A), n >>= 1;
    }
    return B;
}
int main()
{
    int t,n;
    cin >> t;
    while (t--)
    {
        vector<vector<int> > A(3, vector<int>(3));
        A[0][0] = 2, A[0][1] = 1, A[0][2] = 0;
        A[1][0] = 2, A[1][1] = 2, A[1][2] = 2;
        A[2][0] = 0, A[2][1] = 1, A[2][2] = 2;
        cin >> n;
        A = power(A, n);
        cout << A[0][0] << endl;
    }
    return 0;
}
时间: 2024-08-04 15:28:40

POJ 3734的相关文章

POJ 3734 Blocks

                                                         POJ 3734   Blocks Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Description Panda has received an assignment of painting a line of blocks. Since Panda is such an

[POJ 3734] Blocks (矩阵快速幂、组合数学)

Blocks Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3997   Accepted: 1775 Description Panda has received an assignment of painting a line of blocks. Since Panda is such an intelligent boy, he starts to think of a math problem of paint

POJ 3734 Blocks (矩阵快速幂)

题目链接:http://poj.org/problem?id=3734 <挑战程序设计竞赛>202页.与单纯的用递推式与矩阵快速幂求第N项不同,设染到第i个方块为止,红绿都是偶数的方案数目为a,红绿恰有一个是偶数方案数目为b,红绿都是奇数方案数目为c, 则: a[i+1] = 2 * a[i] + b[i] b[i+1] = 2 * a[i]+2 * b[i]+2 * c[i] c[i+1] = b[i] + 2 * c[i] 之后构建3*3矩阵求解 代码: 1 typedef vector&

poj 3734 Blocks 【矩阵快速幂】

Blocks Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4529 Accepted: 2044 Description Panda has received an assignment of painting a line of blocks. Since Panda is such an intelligent boy, he starts to think of a math problem of painting.

[POJ 3734] Blocks 指数型生成函数

题意 有红, 黄, 蓝, 绿四种颜色的砖头. 现在你要将 $n$ 个砖头放成一排. 蓝色, 绿色的砖头的个数必须为偶数. 问最终放置的方案数. n <= 10 ^ 9 . 分析 构建指数型生成函数. $R(x) = Y(x) = \sum_{k = 0} ^ {\infty} \frac{x ^ k}{k !} = e ^ x$ . $B(x) = G(x) = \sum_{k = 0} ^ {\infty} \frac{x ^ {2k}}{(2k)!} = \frac{e ^ x + e ^

poj 3734 方块涂色 求红色 绿色方块都为偶数的方案数 (矩阵快速幂)

N个方块排成一列 用红,蓝,绿,黄4种颜色去涂色,求红色方块 和绿色方块个数同时为偶数的 方案数 对10007取余 Sample Input 212Sample Output 2//(蓝,黄)6//(红红,蓝蓝,蓝黄,绿绿,黄蓝,黄黄) 1 # include <iostream> 2 # include <cstdio> 3 # include <cstring> 4 # include <algorithm> 5 # include <map>

POJ 3734 Blocks(矩阵快速幂加递推)

Blocks Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6133   Accepted: 2931 Description Panda has received an assignment of painting a line of blocks. Since Panda is such an intelligent boy, he starts to think of a math problem of paint

POJ 3734 生成函数

题意:一排n长度的砖,有四种颜色,红色绿色是偶数,有少染色方式. 分析: 泰勒展开式: chx = (e^x+e^(-x))/2 = 1 + x^2/2! + x^4/4! + x^6/6! + ... ...shx = (e^x-e^(-x))/2 = x + x^3/3! + x^5/5! + x^7/7! + ... ...

poj 3734 矩阵快速幂+YY

题目原意:N个方块排成一列,每个方块可涂成红.蓝.绿.黄.问红方块和绿方块都是偶数的方案的个数. sol:找规律列递推式+矩阵快速幂 设已经染完了i个方块将要染第i+1个方块. a[i]=1-i方块中,红.绿方块数量都是偶数的方案数 b[i]=1-i方块中,红.绿方块数量一个是偶数一个是奇数的方案数(红even绿odd 或 红odd绿even) c[i]=1-i方块中,红.绿方块数量都是奇数的方案数 可以得出递推公式: a[i+1]=2*a[i]+b[i] b[i+1]=2*a[i]+2*b[i