• HDU3519_Lucky Coins Sequence_推公式_矩阵加速


    这道题真好,体现了思想的灵活性。要3个连续状态以上嘛,好,那我就求出

    只有1~2个状态的数量,最后总数减去即可。美妙,完结。

    /*
    *State:    3519    0MS    256K    2354 B    
    *题目大意:
    *        给定n个硬币,硬币有两种状态0或1,可以翻转,总共有2^n种
    *        状态,规定如果有连续3个硬币的状态一样,即是特殊串。要求
    *        特殊串的个数。
    *解题思路:
    *        已知总数目,那么可以用相反的思想求出该串状态不含有3个
    *        连续一样的数目,然后用总数去减。
    *        长度为 n 的 01 串一共有 2^n 种不同的排列方法 ,
    *        设 f(n) 为长度是 n 的不包含连续 3 个或以上相同的 1 或 0 的 01 串 ,
    *        则 f(1)=2,f(2)=4,f(3)=6,f(4)=10
    *        当 n>4 的时候 , 分情况考虑 :
    *            1、   如果是以 00 或者 11 结尾 , 则分别有 f(n-2)/2 种情况 , 
    *            加起来就是 f(n-2) 种 .
    *            2、   如果是以 01 或者 10 结尾 , 则第 n 个字符要和第 n-1 个
    *            字符不一样 , 那么分别有 f(n-1)/2 种 , 加起来就是 f(n-1)
    *        则统计起来就是 f(n)=f(n-1)+f(n-2)。之后构造矩阵即可。
    *解题感想:
    *        这道题目是搜题解的,表示做法其实也就一般,关键看能否想到用反推,还有
    *        公式。
    *        由于最后有一步减法,由于是模的关系,有可能结果为负,注意模减法的特殊性。
    *        由于这个错误贡献了两个wa,还查了半个小时不止。最后还好乱给出测试数据了嘻。
    */
    View Code
      1 #include <iostream>
      2 #include <cmath>
      3 #define maxn 3
      4 
      5 using namespace std;
      6 
      7 struct Mat
      8 {
      9     int m, n;
     10     int d[maxn][maxn];
     11     void init(int m, int n) 
     12     {
     13         this->m = m;
     14         this->n = n;
     15         memset(d, 0, sizeof(d));
     16     }
     17     void initE(int size)                              //生成单位阵
     18     {
     19         m = n = size;
     20         for(int i = 0; i < n; i ++)
     21         {
     22             for(int j = 0; j < n; j ++)
     23             {
     24                 d[i][j] = i==j;
     25             }
     26         }
     27     }
     28     Mat operator * (const Mat & mat) const
     29     {
     30         static Mat res;
     31         res.init(m, mat.n);
     32         for(int i = 0; i < res.m; i ++)
     33         {
     34             for(int k = 0; k < n; k ++)
     35             {
     36                 if(d[i][k]==0)    continue;
     37                 for(int j = 0; j < res.n; j ++)
     38                 {
     39                     res.d[i][j] += d[i][k] * mat.d[k][j];
     40                 }
     41             }
     42         }
     43         return res;
     44     }
     45     Mat mul_mod(const Mat & mat, int mod) const
     46     {
     47         static Mat res;
     48         res.init(m, mat.n);
     49         for(int i = 0; i < res.m; i ++)
     50         {
     51             for(int k = 0; k < n; k ++)
     52             {
     53                 if(d[i][k]==0)    continue;
     54                 for(int j = 0; j < res.n; j ++)
     55                 {
     56                     res.d[i][j]=(res.d[i][j]+d[i][k]*mat.d[k][j]) % mod;
     57                 }
     58             }
     59         }
     60         return res;
     61     }
     62     void pow_mod(int k, int mod)                      //this = this^k % mod;
     63     {
     64         static Mat a;
     65         a = *this;
     66         for(this->initE(n); k; k>>=1, a=a.mul_mod(a, mod))
     67             if(k&1)    *this=this->mul_mod(a, mod);
     68     }
     69     void view_arr()
     70     {
     71         for(int i = 0; i < m; i++)
     72         {
     73             for(int j = 0; j < n; j++)
     74                 cout << d[i][j] << " ";
     75             cout << endl;
     76         }
     77     }
     78 };
     79 
     80 int mod_pow(int a,int k,int m) 
     81 {
     82     static int r;
     83     for(r=1;k;k>>=1,a=a*a%m)    if(k&1)    r=r*a%m;
     84     return r;
     85 }
     86 
     87 int main(void)
     88 {
     89 #ifndef ONLINE_JUDGE
     90     freopen("in.txt", "r", stdin);
     91 #endif
     92     int n, mod;
     93     
     94     mod = 10007;
     95 
     96     while(scanf("%d", &n) == 1)
     97     {
     98         Mat a;
     99         a.init(2, 2);
    100         a.d[0][0] = a.d[0][1] = a.d[1][0] = 1;
    101         a.d[1][1] = 0;
    102         if(n == 1 || n == 2)
    103         {
    104             printf("0\n");
    105             continue;
    106         }
    107         a.pow_mod(n - 2, mod);
    108         int tol = mod_pow(2, n, mod);
    109         int fn = (a.d[0][0] * 4 + a.d[0][1] * 2) % mod;
    110         //cout << "fn: " << fn << endl;
    111         //cout << tol << endl;0
    112         printf("%d\n", ((tol - fn) % mod + mod) % mod);
    113     }
    114     return 0;
    115 }
  • 相关阅读:
    核函数矩阵为什么要是positive semidefinite的
    Autoencoders
    Statistics与Machine Learning有什么区别
    [zz]Using SyncTeX with LaTeX
    Metric Learning的一个疑惑
    [zz]Latex中texworks编辑器正向反向跳转搜索
    [zz]Python3.x新特性
    LyX 2.0.5中文排版
    function
    多行文字结尾显示省略号
  • 原文地址:https://www.cnblogs.com/cchun/p/2619554.html
Copyright © 2020-2023  润新知