HDU - 2842 Chinese Rings 矩阵快速幂

题目大意:有n个环,刚开始都是on状态,可以随便改第一个的状态,其他的话,只有前面的k个off掉,第k+1个on,才可以操控第k+2个的状态

问要让n个都变成off状态,需要多少步

解题思路:要让第n个是off,只有先让前n-2个都off,也就是说需要f(n-2)步了。然后再把第n个变成off,需要1步。

之后要把剩下的n-1个都off掉的话,只有先把前面的n-2个都变成on,才能去操控第n-1个,也就是说剩下n-1个都是on的,现在的问题就转成了怎么把n-1都变成off,共需要f(n-1)步

所以f(n) = 2 * f(n-2) + 1 + f(n-1)

#include<cstdio>
typedef long long ll;
const int mod = 200907;
const int N = 3;
int n;
struct Matrix{
    ll mat[N][N];
}A, B, tmp;

void init() {
    for(int i = 0; i < N; i++)
        for(int j = 0; j < N; j++) {
            A.mat[i][j] = B.mat[i][j] = 0;
            if(i == j)
                B.mat[i][j] = 1;
        }
    A.mat[0][0] = A.mat[0][1] = A.mat[2][0] = A.mat[2][2] = 1;
    A.mat[1][0] = 2;
}

Matrix matMul(Matrix x, Matrix y) {
    for(int i = 0; i < N; i++)
        for(int j = 0; j < N; j++) {
            tmp.mat[i][j] = 0;
            for(int k = 0; k < N; k++)
                tmp.mat[i][j] += (x.mat[i][k] * y.mat[k][j]) % mod;
        }
    return tmp;
}

void solve() {
    while(n) {
        if(n & 1)
            B = matMul(B,A);
        A = matMul(A,A);
        n >>= 1;
    }
}

int main() {
    while(scanf("%d", &n) != EOF && n) {
        if(n == 1) {
            printf("1\n");
            continue;
        }
        else if(n == 2) {
            printf("2\n");
            continue;
        }
        n -= 2;
        init();
        solve();
        printf("%I64d\n", (2 * B.mat[0][0] + B.mat[1][0] + B.mat[2][0]) % mod);
    }
    return 0;
}
时间: 2024-10-06 17:22:11

HDU - 2842 Chinese Rings 矩阵快速幂的相关文章

HDU 2842 Chinese Rings(矩阵快速幂+递推)

题目地址:HDU 2842 这个游戏是一个九连环的游戏. 假设当前要卸下前n个环.由于要满足前n-2个都卸下,所以要先把前n-2个卸下,需要f(n-2)次.然后把第n个卸下需要1次,然后这时候要卸下第n-1个,然后此时前n-2个都已经被卸下了.这时候把前n-2个都卸下与都装上所需的次数是一样的,因为卸下与装上的规则是一样的.所以又需要f(n-2)次,这时候前n-1个都在上面,卸下前n-1个需要f(n-1)次. 所以,总共需要2*f(n-2)+f(n-1)+1次. 然后构造如下矩阵. 1,2,1

HDU 2842 (递推+矩阵快速幂)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2842 题目大意:棒子上套环.第i个环能拿下的条件是:第i-1个环在棒子上,前i-2个环不在棒子上.每个环可以取下或放上,cost=1.求最小cost.MOD 200907. 解题思路: 递推公式 题目意思非常无聊,感觉是YY的. 设$dp[i]$为取第i个环时的总cost. $dp[1]=1$,$dp[2]=2$,前两个环取下是没有条件要求的. 从i=3开始,由于条件对最后的环限制最大,所以从最后一

HDU 2842 Chinese Rings(矩阵高速功率+递归)

职务地址:HDU 2842 这个游戏是一个九连环的游戏. 如果当前要卸下前n个环.由于要满足前n-2个都卸下,所以要先把前n-2个卸下.须要f(n-2)次.然后把第n个卸下须要1次,然后这时候要卸下第n-1个.然后此时前n-2个都已经被卸下了.这时候把前n-2个都卸下与都装上所需的次数是一样的.由于卸下与装上的规则是一样的. 所以又须要f(n-2)次.这时候前n-1个都在上面,卸下前n-1个须要f(n-1)次. 所以.总共须要2*f(n-2)+f(n-1)+1次. 然后构造例如以下矩阵. 1,2

HDU 2842 Chinese Rings (带常数矩阵+矩阵快速幂)

HDU 2842 Chinese Rings (带常数矩阵+矩阵快速幂) ACM 题目地址:HDU 2842 Chinese Rings 题意: 一种中国环,解开第k个环需要先解开前(k-2)个环,并留有第(k-1)环.问解开n环最少需要几步. 分析: 设f(n)表示解开n环. 1. 由于游戏规则,解开n环不能一下子把n-1全解开了,否则第n个就没法拿掉了. 2. 得先拿掉第n个:先完成f(n-2),然后再拿掉第n环. 3. 然后放回前(n-2),其实这也是f(n-2),因为是一个逆的过程. 4

HDU - 2842 Chinese Rings

Description Dumbear likes to play the Chinese Rings (Baguenaudier). It's a game played with nine rings on a bar. The rules of this game are very simple: At first, the nine rings are all on the bar. The first ring can be taken off or taken on with one

HDU 2604 Queuing (矩阵快速幂)

HDU 2604 Queuing (矩阵快速幂) ACM 题目地址:HDU 2604 Queuing 题意: n个人排队,f表示女,m表示男,包含子串'fmf'和'fff'的序列为O队列,否则为E队列,有多少个序列为E队列. 分析: 矩阵快速幂入门题. 下面引用巨巨解释: 用f(n)表示n个人满足条件的结果,那么如果最后一个人是m的话,那么前n-1个满足条件即可,就是f(n-1): 如果最后一个是f那么这个还无法推出结果,那么往前再考虑一位:那么后三位可能是:mmf, fmf, mff, fff

HDU 2254 奥运(矩阵快速幂+二分等比序列求和)

HDU 2254 奥运(矩阵快速幂+二分等比序列求和) ACM 题目地址:HDU 2254 奥运 题意: 中问题不解释. 分析: 根据floyd的算法,矩阵的k次方表示这个矩阵走了k步. 所以k天后就算矩阵的k次方. 这样就变成:初始矩阵的^[t1,t2]这个区间内的v[v1][v2]的和. 所以就是二分等比序列求和上场的时候了. 跟HDU 1588 Gauss Fibonacci的算法一样. 代码: /* * Author: illuz <iilluzen[at]gmail.com> * B

HDU 2604 Queuing,矩阵快速幂

题目地址:HDU 2604 Queuing 题意: 略 分析: 易推出:   f(n)=f(n-1)+f(n-3)+f(n-4) 构造一个矩阵: 然后直接上板子: /* f[i] = f[i-1] + f[i-3] + f[i-4] */ #include<cstdio> #include<cstring> using namespace std; const int N = 4; int L, M; struct mtx { int x[N+1][N+1]; mtx(){ mem

hdu 2243 AC自动机 + 矩阵快速幂

// hdu 2243 AC自动机 + 矩阵快速幂 // // 题目大意: // // 给你一些短串,问在长度不超过k的任意串,包含至少一个这些短串的其中 // 一个.问这样的串有多少个. // // 解题思路: // // 首先, 包含和不包含是一种互斥关系,包含+不包含 = 全集u.全集的答案就是 // 26 ^ 1 + 26 ^ 2 + .... + 26 ^ k.不包含的比较好求.构建一个自动机,得到 // 一个转移矩阵A.表示状态i能到状态j的方法数.而这些状态中都是不包含所给的 //