POJ 3734_Blocks
2016-02-16 21:22
369 查看
题意:
用红绿蓝黄四种颜色对一序列n个方块涂色,求出绿和红色方块数同时为偶数的染色方案数。mod=10007分析:
dp+矩阵快速幂首先明确有三种状态:
红和绿均为偶数
红和绿只有一个为奇数
红和绿均为奇数
设前三种方案数分别为ai,bi,ci,则可以得到以下递推式:
ai+1=2∗ai+bibi+1=2∗ai+2∗bi+2∗cici+1=2∗ci
再利用矩阵快速幂求解即可。
代码:
#include<cstdio> #include<iostream> #include<cstdio> using namespace std; typedef long long ll; const int mod = 10007; const int N=3; struct Matrix { int row,cal; ll m ; Matrix() { row=3, cal=3; m[0][0]=2, m[0][1]=1, m[0][2]=0; m[1][0]=2, m[1][1]=2, m[1][2]=2; m[2][0]=0, m[2][1]=1, m[2][2]=2; } }; Matrix init(Matrix a, ll t) { for(int i = 0; i < a.row; i++) for(int j = 0; j < a.cal; j++) a.m[i][j] = t; return a; } Matrix mul(Matrix a,Matrix b) { Matrix ans; ans.row = a.row, ans.cal = b.cal; ans = init(ans,0); for(int i = 0; i < a.row; i++) for(int j = 0; j < b.cal; j++) for(int k = 0; k < a.cal; k++) ans.m[i][j] = (ans.m[i][j] + a.m[i][k] * b.m[k][j])%mod; return ans; } ll quick_pow(ll n) { Matrix ans, t; ans.row=1, ans.cal=3; ans.m[0][0]=1, ans.m[0][1] = 0, ans.m[0][2]=0; while(n) { if(n&1) ans = mul(ans, t); t = mul(t, t); n>>=1; } return ans.m[0][0]; } int main (void) { int T;scanf("%d",&T); int n; while(T--){ scanf("%d",&n); printf("%d\n",quick_pow(n)); } return 0; }
相关文章推荐
- HTML5的canvas画布常用绘图命令总结
- python 正则表达式
- Java描述贪心算法求解单元点最短路径问题
- c++实用语法
- SharedPreferences的使用
- 推荐几个swift学习网站
- Android 中的Intent在两个Acitvity传递数据示例
- Linux环境变量设置
- 笔试面试总结
- 好用的C++数据库访问层
- 构建ASP.NET MVC5+EF6+EasyUI 1.4.3+Unity4.x注入的后台管理系统--工作流演示截图
- java中goto语句
- AT&T格式汇编学习
- uCrop图片裁剪开源库使用总结
- 【转载】6个用好大数据的秘诀
- 第6课:精通Spark集群搭建与测试
- MySQL知识(一)——数据库概念及基本操作
- shell 变量的使用
- ssmmaven 配置文件
- 使用EL表达式需要注意的