标签:des style blog http color os
1 2 9 1005
1 2 341 0
我承认自己的英语渣!
然后现在标程解:
解题思路:
第一环可以随时取下或者套上
一次只能取下或者套上一环
设要取下的是第k环,那么前k-2环必然在杆下,第k-1环必然在杆上,只有这样第k环才能取下,并且取下之后,第k-1环还在杆上,前k-2环在杆下(套上的规则也是类似)
玩1连环,直接取下,ok;
玩2连环,先下第二环(根据3),然后就相当于解1连环了;
玩3连环,先下第一环,之后第三环可以摘下(也是根据3),这个时候只有第二环孤零零地在杆上,之后我们把第一环套上,问题转化为2连环了;
。。。。。。。。。。。
玩k连环,那么第k环是要解下的,而要解下第k环,我们就要先解下前k-2环,这样在杆上的第k环可以依靠在杆上的第k-1环解下(规则3)。第k环解下之后,杆上只有第k-1环,前k-2环在杆下。如果前k-2环不上去,第k-1环就无法解下。所以我们要上前k-2环(稍微一想就知道,上i个环和下i个环的最少步骤必然是相等的,因为是逆过程)好了,上了前k-2环之后,此时杆上就排好了k-1环接下来怎么办?对,递归!
设f[n]是下n连环的最少步骤。那么,要先下前n-2,然后再下第n,然后安装前n-2,然后下前n-1
所以,f[n]=f[n-2]+1+f[n-2]+f[n-1]
=f[n-1]+2*f[n-2]+1
F[0]=0,f[1]=1
可以矩阵乘法了,如果不嫌麻烦
生成函数。
设G(x)=f[0]+f[1]*x+f[2]*x^2+f[3]*x^3+f[4]*x^4+……+f[n]*x^n+….
那么x*g(x)= f[0]*x+f[1]*x^2+f[2]*x^3+f[3]*x^4+….+f[n-1]*x^n+…
并且2*x^2*g(x)= 2*f[0]*x^2+2*f[1]*x^3+2*f[2]*x^4+.+2*f[n-1]*x^n
第一式减下两式,并且根据递推关系,得
(1-x-2*x^2)G(x)=f[0]+f[1]*x-f[0]*x+x^2+x^3+x^4+….+x^n+…
=x+x^2+x^3+…+x^n+…=x/(1-x) (生成函数x没有实际意义
,所以认为无穷级数收敛)
所以G(x)=(x/(1-x))/(1-x-2*x*x)=x/((1-x)*(1+x)*(1-2*x))
将其展开为c/(ax+b)的形式,得到
G(x)= - ( 1/(1-x)*3/2+1/(1+x)*1/2 )/3+ 1/(1-2*x)*2/3
根据1/(1-x)=1+x+x^2+….+x^n+…
得到f[n]= (2^(n+2)-3-(-1)^n)/6
推导有点耗时呢,用其它方法可以么?
注意到这是一个带有常数的线性递推关系。先求对应线性齐次方程的通解,然后求一个特解,然后组合起来就好了(还记得常微分方程吧,与那个类似)
对应的特征方程是x*x=x+2,两个特征根是2与-1
设f[n]=c1*2^n+c2*(-1)^n+c,代入递推f[n]=f[n-1]+2*f[n-2]+1
那么,因为2和-1是那个特征方程的特征跟,所以c1,c2以及含幂的项都抵消了,所以
c=c+2*c+1
所以c=-1/2,再讲f[0],f[1]代入,解得f[n]= -(-1)^n/6+2^(n+1)/3-1/2,与生成函数的一样。
求出公式之后,把分母变成逆元,把幂模掉phi(p),模平方乘法都不需要,因为p只有10000量级,乘以不到100个数。
--反正我没看懂,太渣了!
然后ORZ月月鸟的矩阵快速米!
构造一个这样的矩阵{1 2 1
1 0 0
0 0 1}
然后矩阵的N次幂就OK了,构造矩阵真是一个大学问;
PS:答案就是矩阵中MP[0][0]+MP[0][2]的值;具体看代码(虽然这是不好的风格,我说不上来)
#include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> #include<set> #include<map> #include<vector> #include<queue> #include<string> using namespace std; #define inf 19999999 #define N 30000 typedef long long ll; struct matrix { int a[4][4]; }re,rx; int n; matrix mul(matrix x,matrix y)//矩阵快速米 { matrix tep; memset(tep.a,0,sizeof(tep.a)); for (int i=0;i<3;i++) for (int j=0;j<3;j++){ for (int k=0;k<3;k++) tep.a[i][j]+=x.a[i][k]*y.a[k][j]; tep.a[i][j]%=10007; } return tep; } void calc(int n) { while (n) { if (n&1) rx=mul(rx,re); n>>=1; re=mul(re,re); } printf("%d\n",(rx.a[0][0]+rx.a[0][2])%10007);//求值的操作 } int main() { while (scanf("%d",&n)!=EOF){ memset(re.a,0,sizeof(re.a)); memset(rx.a,0,sizeof(rx.a)); re.a[0][0]=1; re.a[0][1]=2; re.a[0][2]=1;//初始矩阵 re.a[1][0]=1; re.a[2][2]=1; rx.a[0][0]=1; rx.a[1][1]=1; rx.a[2][2]=1;//我构造了一个单位矩阵,方便后面的处理 n--;//-1是因为我们从3开始的 calc(n); } return 0; }
ORZ能找周期的ZZ,真是什么姿势A题的都有
标签:des style blog http color os
原文地址:http://www.cnblogs.com/forgot93/p/3825287.html