poj 3734 矩阵快速幂、母函数
2014-08-18 19:47
417 查看
题意:
用四中颜色的漆料去粉刷N盒子,求使红色和绿色盒子数量为偶数的方案的个数。
矩阵快速幂:
构造矩阵
2 1 1 0
1 2 0 1
1 0 2 1
0 1 1 2
矩阵的构造原理:
已知红色和绿色为偶数
第一个数为red、green均为偶数的种数
第二个数为red为奇数,green为偶数的种数
第三个数为green为奇数、red为偶数的种数
第四个数为red、green均为奇数的种数
矩阵转移分析 N-1 -> N
(1,1)(1,1)*2(添加yellow或者blue都可以继续保持均为偶数);
(1,2)*1(red为奇数,再添加一个red,得到均为偶数);
(1,3)*1(green为奇数,再添加一个green,得到均为偶数)
(1,4)*0(无论如何一个状态内无法得到两个均为偶数)。
将所有情况加和就得到了,N状态下,两个均为偶数的数量了。
其他位置情况分析类同。
方法分析来自@vici,大神。
/*************************************************************************
> File Name: poj3734.cpp
> Author: cy
> Mail: 1002@qq.com
> Created Time: 2014/8/18 17:40:08
************************************************************************/
#include<iostream>
#include<cstring>
#include <algorithm>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<iomanip>
#include<list>
#include<deque>
#include<map>
#include <stdio.h>
#include <queue>
#define maxn 50000+5
#define inf 0x3f3f3f3f
#define INF 0x3FFFFFFFFFFFFFFFLL
#define rep(i,n) for(i=0;i<n;i++)
#define reP(i,n) for(i=1;i<=n;i++)
#define ull unsigned long long
#define ll long long
#define cle(a) memset(a,0,sizeof(a))
#define mod 10007
using namespace std;
struct node
{
int num[5][5];
void init(){
cle(num);
}
};
node cal(node a,node b){
int i,j,k;
node c;
c.init();
rep(i,4){
rep(j,4){
rep(k,4){
c.num[i][j]+=a.num[i][k]*b.num[k][j];
c.num[i][j]%=mod;
}
}
}
return c;
}
node mul(node a,int k)
{
if(k==1)return a;
if(k%2==1)return cal(mul(a,k-1),a);
else
{
node temp=mul(a,k/2);
return cal(temp,temp);
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
#endif
int T;
scanf("%d",&T);
int n;
node val;
int i,j;
int num[16]={2,1,1,0,1,2,0,1,1,0,2,1,0,1,1,2};
rep(i,4)rep(j,4)val.num[i][j]=num[i*4+j];
while(T--)
{
scanf("%d",&n);
node ans=val;
if(n==1)
{
cout<<2<<endl;continue;
}
ans=mul(val,n);
printf("%d\n",ans.num[0][0]%mod);
}
return 0;
}
用四中颜色的漆料去粉刷N盒子,求使红色和绿色盒子数量为偶数的方案的个数。
矩阵快速幂:
构造矩阵
2 1 1 0
1 2 0 1
1 0 2 1
0 1 1 2
矩阵的构造原理:
已知红色和绿色为偶数
第一个数为red、green均为偶数的种数
第二个数为red为奇数,green为偶数的种数
第三个数为green为奇数、red为偶数的种数
第四个数为red、green均为奇数的种数
矩阵转移分析 N-1 -> N
(1,1)(1,1)*2(添加yellow或者blue都可以继续保持均为偶数);
(1,2)*1(red为奇数,再添加一个red,得到均为偶数);
(1,3)*1(green为奇数,再添加一个green,得到均为偶数)
(1,4)*0(无论如何一个状态内无法得到两个均为偶数)。
将所有情况加和就得到了,N状态下,两个均为偶数的数量了。
其他位置情况分析类同。
方法分析来自@vici,大神。
/*************************************************************************
> File Name: poj3734.cpp
> Author: cy
> Mail: 1002@qq.com
> Created Time: 2014/8/18 17:40:08
************************************************************************/
#include<iostream>
#include<cstring>
#include <algorithm>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<iomanip>
#include<list>
#include<deque>
#include<map>
#include <stdio.h>
#include <queue>
#define maxn 50000+5
#define inf 0x3f3f3f3f
#define INF 0x3FFFFFFFFFFFFFFFLL
#define rep(i,n) for(i=0;i<n;i++)
#define reP(i,n) for(i=1;i<=n;i++)
#define ull unsigned long long
#define ll long long
#define cle(a) memset(a,0,sizeof(a))
#define mod 10007
using namespace std;
struct node
{
int num[5][5];
void init(){
cle(num);
}
};
node cal(node a,node b){
int i,j,k;
node c;
c.init();
rep(i,4){
rep(j,4){
rep(k,4){
c.num[i][j]+=a.num[i][k]*b.num[k][j];
c.num[i][j]%=mod;
}
}
}
return c;
}
node mul(node a,int k)
{
if(k==1)return a;
if(k%2==1)return cal(mul(a,k-1),a);
else
{
node temp=mul(a,k/2);
return cal(temp,temp);
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
#endif
int T;
scanf("%d",&T);
int n;
node val;
int i,j;
int num[16]={2,1,1,0,1,2,0,1,1,0,2,1,0,1,1,2};
rep(i,4)rep(j,4)val.num[i][j]=num[i*4+j];
while(T--)
{
scanf("%d",&n);
node ans=val;
if(n==1)
{
cout<<2<<endl;continue;
}
ans=mul(val,n);
printf("%d\n",ans.num[0][0]%mod);
}
return 0;
}
相关文章推荐
- poj 3734 Blocks (矩阵快速幂优化的动态规划)
- poj3734--blocks(矩阵快速幂)
- 文章标题 POJ 3734 : Blocks (矩阵快速幂)
- Poj 3734(矩阵快速幂)
- [POJ 3734] Blocks (矩阵快速幂、组合数学)
- 【POJ 3734 Blocks】+ 矩阵快速幂
- POJ3734 矩阵快速幂
- POJ 3734 (矩阵快速幂+染色问题)
- poj-3734(矩阵快速幂+推导)
- poj 3734 Blocks 【矩阵快速幂】
- 【POJ 3734】【用母函数推公式 或者 矩阵幂】 Blocks【现要给n块砖染红、蓝、绿、黄四种颜色。要求被染成红色和绿色的砖块数量必须为偶数,问染色方案数】
- Poj 3734 Blocks【矩阵快速幂+递推】
- poj 3734 Blocks【矩阵快速幂染色】
- POJ 3734 Blocks【用母函数推公式|矩阵乘法】
- poj 3734 方块涂色 求红色 绿色方块都为偶数的方案数 (矩阵快速幂)
- Blocks(POJ 3734 矩阵快速幂)
- POJ 3734 Blocks(矩阵快速幂)
- poj 3734 <矩阵快速幂模版>
- poj 3734 Blocks(矩阵快速幂)
- POJ 3734 Blocks(dp、矩阵快速幂)