POJ3734Blocks DP&&矩阵快速幂
2014-06-03 19:00
316 查看
题目链接:http://poj.org/problem?id=3734
Blocks
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
Sample Output
方法二:DP+矩阵快速幂
Blocks
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 3922 | Accepted: 1744 |
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; }
相关文章推荐
- hdu 2276 Kiki & Little Kiki 2(矩阵快速幂)
- POJ 3233 Matrix Power Series (矩阵&快速等比数列求和取模)
- 再论斐波那契数列(矩阵&快速幂)
- hdu 5171 GTY's birthday gift (矩阵快速幂求类斐波那契数列)
- HDU 5171 GTY's birthday gift(矩阵快速幂)
- 【递推&矩阵快速幂】hdu 2604
- HDU 5171 GTY's birthday gift (矩阵快速幂)
- NYOJ 300 && hdu 2276 Kiki & Little Kiki 2 (矩阵快速幂)
- POJ 3233 && NYOJ 298 Matrix Power Series(矩阵快速幂)
- HDU - 5171 GTY's birthday gift (矩阵快速幂)
- 矩阵快速幂小结&反思 不断补充ing
- foj 1692 矩阵快速幂&&循环矩阵优化
- 利用矩阵&快速幂解决斐波那契数列相关题目小结
- hdu 4291 A Short problem 打表找规律&矩阵快速幂
- hdu 5015 233 Matrix 2014 ACM/ICPC Asia Regional Xi'an Online 矩阵快速幂
- HDU 2276 Kiki & Little Kiki 2 矩阵快速幂
- HDU3221Brute-force Algorithm(矩阵快速幂&&指数降幂)
- 多校第九场:贪心+矩阵快速幂中间优化+线性递推&线段树递推
- [BZOJ1898] Swamp 沼泽鳄鱼 && 矩阵快速幂
- hdu 5171 GTY's birthday gift(矩阵快速幂)