• ACM-ICPC 2018 焦作赛区网络预赛 L. Poor God Water 矩阵快速幂


    题目链接(VJ):https://nanti.jisuanke.com/t/A2022

    计蒜客:https://nanti.jisuanke.com/t/A2022

    题意:有N个小时,有三种食物(用1 ,2 ,3代替好了),每个小时要吃一种食物,要求任意连续三个小时不能出现111,222,333,132,231,313,323

    的方案数

    题解:最重要的是能找到这个转移关系,转移就是在增加一种食物,可以根据要求推出下面的递推矩阵.

     然后直接矩阵快速幂就好了。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int MOD = 1e9+7;
     4 const int maxn = 20;
     5 #define mod(x) ((x)%MOD)
     6 typedef long long ll;
     7 struct martix{
     8     ll a[maxn][maxn];
     9     friend martix operator * (martix x,martix y)
    10     {
    11         martix ans;
    12         for(int i = 1;i <= 9;i++)
    13         {
    14             for(int j = 1;j <= 9;j++)
    15             {
    16                 ll res = 0;
    17                 for(int k = 1;k <= 9;k++) 
    18                     res += mod((ll)x.a[i][k]*y.a[k][j]);
    19                 ans.a[i][j] = mod(res);
    20             }
    21         }
    22         return ans;
    23     }
    24     friend martix operator ^ (martix x,ll n)
    25     {
    26         martix unit;
    27         memset(unit.a,0,sizeof(unit.a));
    28         for(int i = 1;i <= 9;i++) unit.a[i][i] = 1; 
    29         while(n)
    30         {
    31             if(n&1) unit = unit * x;
    32             x = x * x;
    33             n >>= 1;
    34         }
    35         return unit;
    36     }
    37 };
    38 int main()
    39 {
    40     ll t,n;
    41     cin>>t;
    42     while(t--)
    43     {
    44         cin>>n;
    45         if(n == 1) cout<<3<<endl;
    46         else if(n == 2) cout<<9<<endl;
    47         else
    48         {
    49             martix ans;
    50             ll num[10][10] = {
    51             0,0,0,0,0,0,0,0,0,0,
    52             0,0,1,1,0,0,0,0,0,0,
    53             0,0,0,0,0,1,1,0,0,0,
    54             0,0,0,0,0,0,0,0,1,1,
    55             0,1,1,0,0,0,0,0,0,0,
    56             0,0,0,0,1,0,1,0,0,0,
    57             0,0,0,0,0,0,0,1,1,1,
    58             0,1,0,1,0,0,0,0,0,0,
    59             0,0,0,0,1,1,1,0,0,0,
    60             0,0,0,0,0,0,0,1,1,0,
    61             };
    62             for(int i = 1;i <= 9;i++)
    63             {
    64                 for(int j = 1;j <= 9;j++)
    65                 {
    66                     ans.a[i][j] = num[i][j];
    67                 } 
    68             }
    69             ans = ans ^ (n-2);
    70             ll res = 0;
    71             for(int i = 1;i <= 9;i++)
    72             {
    73                 for(int j = 1;j <= 9;j++)
    74                 {
    75                     res += mod(ans.a[i][j]);
    76                 }
    77             }
    78             cout<<mod(res)<<endl;
    79         }
    80     }
    81     return 0;
    82 }
  • 相关阅读:
    线段的平移和旋转
    《构建之法》第一章读书笔记
    课程大作业总结
    2016.1.8
    2016.1.7
    2016.1.6总结
    初学MFC
    实时控制软件第三次编程作业
    实时控制软件设计第二次编程作业
    实时控制软件设计第一次编程作业
  • 原文地址:https://www.cnblogs.com/Mingusu/p/12389568.html
Copyright © 2020-2023  润新知