hrbust 1401 九连环

本文介绍了一个经典的九连环问题,并通过使用矩阵快速幂的方法求解该问题。对于给定的环数n,文章提供了一种高效计算从柄上摘下n个环所需的最小操作次数的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近学了矩阵快速幂,于是趁热打铁刷了一波题。。。

要加油了!

九连环
Time Limit: 1000 MSMemory Limit: 65536 K
Total Submit: 69(40 users)Total Accepted: 36(33 users)Rating: Special Judge: No
Description
相信大家都玩过九连环的游戏 ,九连环的规则是 :
1第一个环可以在任何时候挂到柄上或者从柄上摘下
2在任何时候,你只能操作一个环
3如果前k-2个环都没有在柄上,并且第k-1个环在柄上,这时如果第k个环在柄上的话,可以把它摘下来,如果它不在柄上,可以把它挂上去

Input
给定一个数n,n不大于10的8次方,你的任务是输出从柄上摘下n个环需要的最小操作次数,测试数据不超过100组。
Output
输出1行,因为结果非常大,所以你需要输出结果对素数10007的余数。
Sample Input

1
2
9

Sample Output

1
2
341

九连环其实很简单,去下第K个之前要保证第K-1个在环上;

如果要去掉K个环,要先去第K个再去第K-1个以此类推...

先推导出转移矩阵之后,直接套矩阵快速幂的模板

最近做的几道题,大体部分都没改,只是改了一下递推矩阵

#include<iostream>
#include<cstdio>
#include<string.h>
#define mem(a,b) memset(a,b,sizeof(a));
#define MAXN 10007
#define LL long long
using namespace std;
LL n;
struct mat
{
    LL a[4][4];
};
mat mat_mul(mat x,mat y)
{
    mat ans;
    mem(ans.a,0);
    for(LL i=0;i<3;i++)
    {
        for(LL j=0;j<3;j++)
        {
            for(LL k=0;k<3;k++)
            {
                ans.a[i][j]+=x.a[i][k]*y.a[k][j];
            }
            ans.a[i][j]%=MAXN;
        }
    }
    return ans;
}
LL pow(LL k)
{
    mat s1,s2;
    mem(s2.a,0);
    mem(s1.a,0);
    s1.a[0][0]=2;s1.a[1][0]=1;s1.a[2][0]=1;
    s2.a[0][0]=1;s2.a[0][1]=2;s2.a[0][2]=1;
    s2.a[1][0]=1;s2.a[2][2]=1;
    while(k)
    {
        if(k&1==1)
        s1=mat_mul(s2,s1);
        s2=mat_mul(s2,s2);
        k>>=1;
    }
    return s1.a[0][0];
}
int main()
{
    while(cin>>n)
    {
        if(n==1)printf("1\n");
        else if(n==2)printf("2\n");
        else
        {
            LL t=pow(n-2);
            printf("%lld\n",t);
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值