首页 > 其他 > 详细

1122 机器人走方格 V4

时间:2016-08-28 23:53:47      阅读:308      评论:0      收藏:0      [点我收藏+]
基准时间限制:1 秒 空间限制:131072 KB 
四个机器人a b c d,在2 * 2的方格里,一开始四个机器人分别站在4个格子上,每一步机器人可以往临近的一个格子移动或留在原地(同一个格子可以有多个机器人停留),经过n步后有多少种不同的走法,使得每个毯子上都有1机器人停留。由于方法数量巨大,输出 Mod 10^9 + 7的结果。
 
Input
输入1个数N(0 <= N <= 10^9)
Output
输出走法的数量 Mod 10^9 + 7
Input示例
1
Output示例
9
思路:矩阵快速幂。
这道题和hdu2232是一样的只不过hud的那到题数据比较小,用dp能过,但这道题必须要矩阵快速幂。这道题的思路可以参考http://blog.csdn.net/womendeaiwoming/article/details/5806700
给出递推:
技术分享
其中f下标表示第i个机器人在第j的方格的方案;
  1 #include<stdio.h>
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<stdlib.h>
  5 #include<queue>
  6 #include<string.h>
  7 using namespace std;
  8 typedef long long LL;
  9 typedef struct node {
 10     LL m[4][4];
 11     node() {
 12         memset(m,0,sizeof(m));
 13     }
 14 } maxtr;
 15 void Init(maxtr *p);
 16 maxtr quick(maxtr ans,LL m);
 17 const LL mod = 1e9 + 7;
 18 LL dp[4][4];
 19 LL dpx[4][4];
 20 int main(void) {
 21     LL n;
 22     scanf("%lld",&n);
 23     if(n == 0) {
 24         printf("1\n");
 25     } else {
 26         maxtr ac;
 27         Init(&ac);
 28         int i,j,z;
 29         maxtr ak = quick(ac,n);
 30         memset(dpx,0,sizeof(dpx));
 31         for(i = 0; i < 4; i++) {
 32             for(j = 0; j < 4; j++) {
 33                 for(z = 0; z < 4; z++) {
 34                     dpx[i][j] = dpx[i][j] + ak.m[i][z]*dp[z][j]%mod;
 35                     dpx[i][j]%=mod;
 36                 }
 37             }
 38         }
 39         int x,y;
 40         LL sum = 0;
 41         for(i = 0; i < 4; i++) {
 42             for(j = 0; j < 4; j++) {
 43                 for(x = 0; x < 4; x++) {
 44                     for(y = 0; y < 4; y++) {
 45                         if(i==j||i==x||i==y||j==x||j==y||x==y)
 46                             continue;
 47                         else {
 48                             sum  = sum + (((dpx[0][i]*dpx[1][j]%mod)*dpx[2][x]%mod)*dpx[3][y])%mod;
 49                             sum %= mod;
 50                         }
 51                     }
 52                 }
 53             }
 54         }
 55         printf("%lld\n",sum);
 56     }
 57     return 0;
 58 }
 59 maxtr E() {
 60     int i,j;
 61     maxtr ans;
 62     for(i = 0 ; i < 4 ; i++) {
 63         for(j = 0 ; j < 4 ; j++) {
 64             if(i == j) {
 65                 ans.m[i][j] = 1;
 66             }
 67         }
 68     }
 69     return ans;
 70 }
 71 void Init(maxtr *p) {
 72     int i,j;
 73     for(i = 0; i < 4; i++) {
 74         fill(p->m[i],p->m[i]+4,1);
 75     }
 76     p->m[0][2] = 0;
 77     p->m[1][3] = 0;
 78     p->m[2][0] = 0;
 79     p->m[3][1] = 0;
 80     memset(dp,0,sizeof(dp));
 81     for(i = 0; i < 4; i++) {
 82         for(j = 0; j < 4; j++) {
 83             if(i == j)
 84                 dp[i][j] = 1;
 85         }
 86     }
 87 }
 88 maxtr quick(maxtr ans,LL m) {
 89     int i,j,z;
 90     maxtr ask = E();
 91     while(m) {
 92         if(m&1) {
 93             maxtr C;
 94             for(i = 0; i < 4; i++) {
 95                 for(j = 0 ; j < 4; j++) {
 96                     for(z = 0; z < 4; z++) {
 97                         C.m[i][j] =  C.m[i][j] + ans.m[i][z]*ask.m[z][j]%mod;
 98                         C.m[i][j]%=mod;
 99                     }
100                 }
101             }
102             ask = C;
103         }
104         maxtr ak;
105         for(i = 0 ; i < 4; i++) {
106             for(j = 0; j < 4; j++) {
107                 for(z = 0 ; z < 4; z++) {
108                     ak.m[i][j] = ak.m[i][j] + ans.m[i][z]*ans.m[z][j]%mod;
109                     ak.m[i][j]%=mod;
110                 }
111             }
112         }
113         ans = ak;
114         m>>=1;
115     }
116     return ask;
117 }

 


1122 机器人走方格 V4

原文:http://www.cnblogs.com/zzuli2sjy/p/5816194.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!