hdu2842Chinese rings

题目链接https://vjudge.net/problem/HDU-2842

题目如下

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 step.
If the first k rings are all off and the (k + 1)th ring is on, then the (k + 2)th ring can be taken off or taken on with one step. (0 ≤ k ≤ 7)

Now consider a game with N (N ≤ 1,000,000,000) rings on a bar, Dumbear wants to make all the rings off the bar with least steps. But Dumbear is very dumb, so he wants you to help him.

Input

Each line of the input file contains a number N indicates the number of the rings on the bar. The last line of the input file contains a number "0".

Output

For each line, output an integer S indicates the least steps. For the integers may be very large, output S mod 200907.

Sample Input

1
4
0

Sample Output

1
10

题目说的是九连环,九连环第一个环可以无条件取下(算作一步),其他第n个环要取下的条件是,第n-1个环没有被取下,第n-2个环被取下。取下环和放上环是可逆的,也就是说步数是相等的

现在我们来考虑三个环都被取下的最少步数

首先取第三个环,条件是第二个环在上面&&第一个环被取下(step=1)然后取下第三个环(step=2)

现在取第二个环,条件第一个环在上面,那么放上第一个环(step=3)然后取下第二个环(step=4)

现在取下第一个环(第一个环可以任意取)(step=5)

那么任意n个环的情况呢,把他们看成三部分,第n个环,第n-1个环,前n-2个环,总共这三部分,可以看成三个环的情况

记取完n个环需要的步数是F(N)   类似前面取三个环的思路

首先取第n个环,条件是n-1个环在上面&&前n-2个环不在上面(step=F(N-2))然后取下第n个环(step=F(N-2)+1)

现在取下第n-1个环,条件是前n-2个环在上面,那么放上前n-2个(step=F(N-2)+1+F(N-2))现在变成了n-1个环,那么直接

step=F(N-2)+1+F(N-2)+F(N-1)

推出F(N)=F(N-1)+2*F(N-1)+1

构造如下矩阵

1  2  0  1            f(n-1)          f(n)

 1  0  0  0    *       f(n-2)   =    f(n-1)

 0  1  0  0             f(n-3)         f(n-2)

 0  0  0  1               1               1

之后矩阵快速幂

代码如下

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int mod=200907;
typedef long long ll;
ll n;
struct matrix
{
	ll s[3][3];
}base;
matrix operator*(matrix a,matrix b)
{
	matrix c;
	memset(c.s,0,sizeof(c.s));
	for(int i=0;i<3;i++)
		for(int j=0;j<3;j++)
		for(int k=0;k<3;k++)
		c.s[i][j]+=(a.s[i][k]%mod)*(b.s[k][j]%mod)%mod;
	return c;
}
ll quick_pow()
{
	if(n==1)return 1;
	if(n==2)return 2;
	matrix a;
	memset(a.s,0,sizeof(a.s));
	memset(base.s,0,sizeof(base.s));
	for(int i=0;i<3;i++)a.s[i][i]=1;
	base.s[0][0]=1,base.s[0][1]=2,base.s[0][2]=1;
	base.s[1][0]=1,base.s[2][2]=1;
	ll k=n-2;
	while(k)
	{
		if(k&1)a=a*base;
		base=base*base;
		k>>=1;
	}
	ll ret;
	ret=(a.s[0][0]%mod)*2+(a.s[0][1]%mod)+(a.s[0][2]%mod);
	return ret%mod;
}
int main()
{
	while(scanf("%I64d",&n)!=EOF&&n)
	{
		ll ret;
		ret=quick_pow();
		cout<<ret<<endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41626975/article/details/82149781
今日推荐