您的位置:首页 > 其它

POJ3734Blocks DP&&矩阵快速幂

2014-06-03 19:00 316 查看
题目链接:http://poj.org/problem?id=3734

Blocks

Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 3922 Accepted: 1744
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. Suppose there are N blocks in a line and each block can be paint red, blue, green or yellow. For some
myterious reasons, Panda want both the number of red blocks and green blocks to be even numbers. Under such conditions, Panda wants to know the number of different ways to paint these blocks.

Input

The first line of the input contains an integer T(1≤T≤100), the number of test cases. Each of the next T lines contains an integer N(1≤N≤10^9) indicating the number of blocks.

Output

For each test cases, output the number of ways to paint the blocks in a single line. Since the answer may be quite large, you have to module it by 10007.

Sample Input
2
1
2

Sample Output
2
6

方法一:找规律  F(n)=4^(n-1)+2^(n-1);

#include <iostream>
#include <cstdio>
using namespace std;
const int mod = 10007;
int quick_mod(int a,int b,int c)
{
int ans=1;
a%=c;
while(b){
if(b&1){
ans=ans*a%c;
b--;
}
b>>=1;
a=a*a%c;
}
return ans;
}
int main()
{
int t,n;
cin>>t;
while(t--){
cin>>n;
int t=(quick_mod(4,n-1,mod)%mod+quick_mod(2,n-1,mod)%mod)%mod;
cout<<t<<endl;
}
return 0;
}

方法二:DP+矩阵快速幂
我们设 DP
[4];

DP[i][0] 表示有i个blocks红色和绿色都是偶数;

DP[i][1] 表示有i个blocks红色是偶数绿色是奇数

DP[i][1] 表示有i个blocks红色是奇数绿色是偶数
DP[i][1] 表示有i个blocks红色是奇数绿色是奇数
dp[i][0]=2*dp[i-1][0](黄色黑色随便放一个有两种选择)+dp[i-1][1](只能放一个绿色的)+dp[i-1][2](放一个红)
同理可以推出其他几种情况
但是由于n为10^9 普通DP会超时 因此我们只能构造矩阵
有了DP公式写出状态转移矩阵就恨轻松了
matrix A={//状态转移矩阵
   2,1,1,0,
   1,2,0,1,
   1,0,2,1,
   0,1,1,2
};
代码如下:
//  DP+矩阵快速度幂
#include <iostream>
#include <cstdio>
using namespace std;
const int mod = 10007;
const int N = 4;
struct matrix
{
int m

;
};
matrix A={//状态转移矩阵
2,1,1,0,
1,2,0,1,
1,0,2,1,
0,1,1,2
};
matrix E={
1,0,0,0,
0,1,0,0,
0,0,1,0,
0,0,0,1
};
matrix multi(matrix a,matrix b)//矩阵乘法
{
matrix c;
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
c.m[i][j]=0;
for(int k=0;k<N;k++)
c.m[i][j]+=a.m[i][k]*b.m[k][j]%mod;
c.m[i][j]%=mod;
}
}
return c;
}
matrix power(matrix A, int k)//矩阵快速幂
{
matrix ans=E,p=A;
while(k){
if(k&1){
ans=multi(ans,p);
k--;
}
k>>=1;
p=multi(p,p);
}
return ans;
}
int main()
{
int t,n;
cin>>t;
while(t--){
cin>>n;
int ans=0;
matrix x=power(A,n);
cout<<x.m[0][0]<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: