zoukankan      html  css  js  c++  java
  • hdu 2842(矩阵高速幂+递推)

    题意:一个中国环的游戏。规则是一个木棒上有n个环,第一个环是能够任意放上或拆下的,剩下的环x假设想放上或拆下必须前一个环x-1是放上的且前x-2个环所有是拆下的,问n个环最少多少次操作能够所有拆掉。


    题解:须要进行递推。首先第一步肯定是要拆第n个环保证操作次数最少。由于后面的环是否存在对前面的环不造成影响,而先拆前面的假设要拆后面的环还是要把前面的放上,f(n)表示拆掉前n个环须要的最少操作次数。先拆第n个要拆前n-2个再拆第n个,花费f(n-2)+1,然后这时是00…0010,要拆第n-1个须要先把前n-2个放上。花费的步数和拆下是一样是f(n-2),这时就是11…1110。所有拆掉就是f(n-1),因此递推公式是f(n) = f(n-1) + 2 * f(n-2) + 1。最后矩阵高速幂即可了。

    #include <stdio.h>
    #include <string.h>
    const int MOD = 200907;
    struct Mat {
        long long g[3][3];
    }ori, res;
    long long n;
    
    Mat multiply(Mat x, Mat y) {
        Mat temp;
        for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++) {
                temp.g[i][j] = 0;
                for (int k = 0; k < 3; k++)
                    temp.g[i][j] = (temp.g[i][j] + x.g[i][k] * y.g[k][j]) % MOD;
            }
        return temp;
    }
    
    void calc(long long n) {
        while (n) {
            if (n & 1)
                ori = multiply(ori, res);
            n >>= 1;
            res = multiply(res, res);
        }
    }
    
    int main() {
        while (scanf("%lld", &n) == 1 && n) {
            if (n == 1 || n == 2) {
                printf("%lld
    ", n);
                continue;
            }
            memset(ori.g, 0, sizeof(ori.g));
            memset(res.g, 0, sizeof(res.g));
            ori.g[0][0] = 2;
            ori.g[0][1] = ori.g[0][2] = 1;
            res.g[0][0] = res.g[0][1] = res.g[2][0] = res.g[2][2] = 1;
            res.g[1][0] = 2;
            calc(n - 2);
            printf("%lld
    ", ori.g[0][0]);
        }
        return 0;
    }
  • 相关阅读:
    Python基础系列----语法、数据类型、变量、编码
    Python基础系列----环境的搭建及简单输入、输出
    Python 从基础------进阶------算法 系列
    Python数据库访问公共组件及模拟Http请求
    急!急!急!请问win32api参数乱码如何解决!
    打印之Lodop
    Elasticsearch 6.7.2 源码编译
    ElasticSearch源码之——Gateway
    ElasticSearch源码之——Netty在Elasticsearch中的应用
    从BIO到Netty
  • 原文地址:https://www.cnblogs.com/mfmdaoyou/p/6955879.html
Copyright © 2011-2022 走看看