POJ 3734 矩阵加速dp
2015-12-28 20:37
369 查看
题意
n长序列,每个位置可染4种颜色,问你第1,2种颜色都染偶数个位置的染色方法数。思路
递推,a[i]表示前i个位置,题中所问,b[i]表示颜色1是偶数且2是奇数的染色方法数,c[i]表示2是偶,1是奇的方法数,d[i]为都是奇数时的方法数a[i] = 2*a[i-1] + b[i-1] + c[i-1]
b[i] = 2*b[i-1] + a[i-1] + d[i-1]
c[i] = 2*c[i-1] + a[i-1] + d[i-1]
d[i] = 2*d[i-1] + b[i-1] + c[i-1]
为了加速递推式的求解,我们使用矩阵加速
这个方程组的系数矩阵B的n次幂再右乘a~d初值的列向量A既可求出
初值是(1,0,0,0)’
实现
#include <iostream> #include <vector> #include <cstring> using namespace std; typedef vector<int> vec; typedef vector<vec> mat; #define push_back pb mat A(4,vec(1,0)); mat B(4,vec(4,1)); mat C(4,vec(4,0)); const int mod = 10007; mat operator*(mat A,mat B){ mat C(A.size(),vec(B[0].size(),0)); for (int i=0;i<A.size();i++){ for (int j=0;j<B[0].size();j++){ for (int k=0;k<A[0].size();k++){ C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % mod; } } } return C; } void pow_mat(int n){ mat tmp(B); for (int i=0;i<C.size();i++) for (int j=0;j<C[0].size();j++) C[i][j] = 0; for (int i=0;i<C.size();i++){ C[i][i] = 1; } while (n > 0){ if (n&1){ C = tmp * C; } tmp = tmp * tmp; n >>= 1; } } int main(){ for (int i=0;i<B.size();i++){ B[i][i] = 2; B[i][B.size()-i-1] = 0; } A[0][0] = 1; ios::sync_with_stdio(false); int n,T; cin>>T; while (T--){ cin>>n; pow_mat(n); cout << (C * A)[0][0] << "\n"; } return 0; }
相关文章推荐
- 从gpu到chromium compositor(cc)详解android4.4 webview chromium v37硬件绘制流程
- 输入带有空格字符串的三种方法
- 京东商品详情页应对“双11”大流量的技术实践
- 杭电2602
- 设计模式之十:观察者模式(Observer)
- 线性代数的学习
- perl 数字<->字符串及其进制间的转换
- opencv2.4.9学习_加载并显示一个图像
- perl pack/unpack
- 从菜鸟走向大数据高手
- perl让人纠结的几个问题
- Linux命令之sed的详解
- 字符串匹配 KMP算法
- 【漫谈机器学习】-前言
- hdu 2060(水题)
- SEO之html5缓存
- hadoop学习;hadoop伪分布搭建
- app开发简单流程
- perl之正则表达式
- c++ 静态成员变量