这个范围使你的计算机不能模拟整个过程了,所以----思考新的算法吧。
这个范围使你的计算机不能模拟整个过程了,所以----思考新的算法吧。
10、第二道调剂的题目:
有2N张牌,编号从1到2N,现在开始洗牌,每次将牌从中间分成两堆,将前一半依次插入偶数位置,后一半依次插入奇数位置
比如N = 3时,一次操作后得到:
1 2 3 4 5 6
4 1 5 2 6 3
接下来继续这个操作,得到
2 4 6 1 3 5
1 2 3 4 5 6
我们会看到3次操作之后,所有的牌回到了原来位置。
现在,请你用一个期望复杂度在O(N)以内的算法,对于给定的N,求出多少次洗牌操作之后,所有的牌都回到了原来的位置。
并且,请尝试证明一下你的复杂度在O(N)以内。
2008/5/5 pongba <pon...@gmail.com>:
矩阵也疯狂(天地之灵收集整理)
1、费伯拉契数列:它是符合这样一个性质的数列:除了开头两个数以外,每个数都是之前两个数之和。
比如以0和1开头的费伯拉契序列叫做标准费伯拉契序列,有
i 0 1 2 3 4 5 6 7 8
f(i) 0 1 1 2 3 5 8 13 21
现在,给你f(0)、f(1)、N和M,请你求出f(N)%M的值(即:编号为N的费伯拉契数除以M的余数)这四个数的范围都不超过2的32次方。
是O(min(m*m, n))
2008/5/5 鋆邓 <tdzl...@gmail.com>:
太大了。M和N都是2的32次方之内O(N)的算法都太大了,M*M更得不到什么效果。
2008/5/5 pongba <pon...@gmail.com>:
2008/5/5 天地之灵 <tdzl...@gmail.com>:
矩 阵也疯狂(天地之灵收集整理)
1、费伯拉契数列:它是符合这样一个性质的数列:除了开头两个数以外,每个数都是之前两个数之和。
比如以0和1开头的费伯拉契序列叫做标准费伯拉契序列,有
i 0 1 2 3 4 5 6 7 8
f(i) 0 1 1 2 3 5 8 13 21
现在,给你f(0)、f(1)、N和M,请你求出f(N)%M的值(即:编号为N的费伯拉契数除以M的余数)这四个数的范围都不超过2的32次方。
这一题,一开始我是想,难道不很简单么?fn mod m = fn-1 mod n + fn-2 mod m,递推就是了。但是我觉得这应该是误解了题意。如果就这么简单的话这题目也没意思了。于是进一步思考,难道说fn mod m有一个表达式可以直接算?fn是没有表达式,但不代表fn mod m没有。联想到mod运算的性质:任何一个数n mod m之后都落在0~m-1之间(可以将0~m-1标在一个m等分的圆环上)。fn有无穷多个,然而fn mod m的值却只可能有有穷多个,将无穷放在有穷里面,猜测应该会出现某种循环。所以我固定一个m,比如5,然后依次列出所有的fn mod 5,发现到f20的时候出现了循环,而且这个循环是从f0,f1开始的。f20的20和5有关系吗?4倍?不肯定。此外首次出现循环的点一定是从f0, f1开始的吗?也不确定。于是尝试另外的m,令m为3,4,6的时候都验证为从f0,f1开始重现循环。但开始发生循环的fx的那个x和m的关系尚不确 定。
目前对于一定会循环只是归纳的结果,还需要证明一定会循环。经过一点考虑,发现,(fn, fn+1)作为一个pair,由于里面的fn只能位于0~m-1之间,所以这个pair只有m*m种可能性,所以必然至少有一个pair必然会在后续的序 列中重现,而一旦重现,考虑到fn+2 = fn+1 + fn,于是某个局部序列便会重复它自身。
总结一下目前得到的结果:fn mod m这个序列并不像fn序列本身那样只能通过递归来求,实质上,fn mod m这个序列的信息量是有限的。至多衍生m*m位必然就会发生循环。所以当给定了一个m,我们只需首先求出那个循环点(O(m*m)),假设其下标是x,然 后fn mod m就等于f (n mod x) mod m了。
首次循环一定是从f0, f1开始的结论待证。
... 走到家,想起来了. 关键是注意到从其它fn, fn+1首次开始循环的话,必然会得到"本应从fn-1就开始循环"的矛盾.
这个算法的复杂性只依赖于m,即O(m*m)(实际上是O(min(m*m, n)).如果要更好的话,除非在那个循环序列里面还有自身的规律.
--
--
刘未鹏(pongba)|C++的罗浮宫
http://blog.csdn.net/pongba
TopLanguage
http://groups.google.com/group/pongba
2008/5/5 鋆邓 <tdzl...@gmail.com>:两项都很大,min一下也小不了。
我想说的是,只要m给定,无论n如何增长,都能在常数时间内计算出来.这已经比平凡的求法好多啦.
不过你应该是说还有更简单的,看样子m这个纬度上的复杂度应该不是O(m)就是O(1).O(1)的话等于就是能够有解析表达式了,不大可能啊.怎么降到O(m)是个问题.
2008/5/5 pongba <pon...@gmail.com>:2008/5/5 鋆邓 <tdzl...@gmail.com>:两项都很大,min一下也小不了。
我想说的是,只要m给定,无论n如何增长,都能在常数时间内计算出来.这已经比平凡的求法好多啦.
不过你应该是说还有更简单的,看样子m这个纬度上的复杂度应该不是O(m)就是O(1).O(1)的话等于就是能够有解析表达式了,不大可能啊.怎么降到O(m)是个问题.
在我感觉,m唯一可能的递推关系是将fn mod m表达为fn mod m-1,可以这样来表达:
X mod M = [ X mod M-1 + (X - X mod M-1) mod M ] mod M
这样的话,结合上面的做法,复杂度能够降到O(m).
难道还有更快的?
> 这个范围使你的计算机不能模拟整个过程了,所以----思考新的算法吧。
>
> 10、第二道调剂的题目:
> 有2N张牌,编号从1到2N,现在开始洗牌,每次将牌从中间分成两堆,将前一半依次插入偶数位置,后一半依次插入奇数位置
> 比如N = 3时,一次操作后得到:
> 1 2 3 4 5 6
> 4 1 5 2 6 3
> 接下来继续这个操作,得到
> 2 4 6 1 3 5
> 1 2 3 4 5 6
> 我们会看到3次操作之后,所有的牌回到了原来位置。
> 现在,请你用一个期望复杂度在O(N)以内的算法,对于给定的N,求出多少次洗牌操作之后,所有的牌都回到了原来的位置。
> 并且,请尝试证明一下你的复杂度在O(N)以内。
>
>
> >
>
--
bool ContactMe(person you)
{
if(you.GoTo("14#344, Tsinghua") && you.Find("Fan Huaiyu"))return true;
if(you.MailTo(" dugu...@gmail.com ") || you.MailTo("
fan...@mails.tsinghua.edu.cn "))return true;
if(you.PhoneTo("13488810330") || you.PhoneTo("01062778689"))return true;
if(you.QQTo("120628812") || you.MSNTo("dugu...@hotmail.com"))return true;
if(you.NetTo(" www.cnblogs.com/duguguiyu "))return true;
return false;
}
> 这个范围使你的计算机不能模拟整个过程了,所以----思考新的算法吧。
2007年ACM/ICPC国际大学生程序设计竞赛亚洲区域赛(南京)有来自全国各地95所高校的658支参赛队,经过激烈角逐,我校在网络预赛中以13名和27名的成绩取得晋级区域赛的两个名额。在为期两天的决赛中,张伟、周郴、王良晶组成的团队以总成绩第八名获得了金牌。另外杜鹏、刘绍辉、陈建群获得铜牌。
-========Orz的分割线=========-
牛人啊!:-)
pangba 你想想 要算一个周期的长度的话 要不要 m^2.
我觉得这个是突破口
1、
我们分析 F(N) = F(N-1)+F(N-2),这是一个显然的线性递推问题。
如果我们将F(N)和F(N-1)组成向量A(n) =( F(N), F(N-1) )
那么就有
F(N+1) = 1* F(N) + 1*F(N-1)
F(N) = 1*F(N) + 0*F(N-1)
A(n+1) = ( F(N)+F(N-1), F(N) )
= A(n) *B
其中B = 1 1
1 0
那么,设A(0) = (F(1), F(0))
则有A(N) = A(0) * B^N
F(N) = (A(0) * B^N) [1] (其中[1]指取出该向量的第二项,这里用了C语言的思维理解向量和矩阵)
= F(1) * ((B^N)[1][0] + F(0) * ((B^N)[1][1])
对于求B^N,我们有lgN的算法来求矩阵的幂。并且,整个运算过程中没有减法和除法,因此我们可以在运算过程中将所有的加法当作模加来计算,所有乘法当作模乘来计算。
你的算法是O(M^2)
M的范围也是很大的
你没有办法在有效时间内做好预处理。
另外,如果你打算做这样的预处理,你需要对每个给定的M都进行计算,你没有足够的空间保存这样的一个表
2008/5/10 鋆邓 <tdzl...@gmail.com>:你的算法是O(M^2)
M的范围也是很大的
你没有办法在有效时间内做好预处理。
另外,如果你打算做这样的预处理,你需要对每个给定的M都进行计算,你没有足够的空间保存这样的一个表
呃,任意一次计算总是给定M的吧。
另,你的算法并没有用到mod M的性质吧。
我们这两个方法的复杂性似乎应该这样来比较,由于涉及到M和N这两个变量,可以假想算法耗时间可以描绘在一个三维空间上的一个二维曲面(但变量的算法复杂性是一个曲线)
pangba 你想想 要算一个周期的长度的话 要不要 m^2.
我觉得这个是突破口
另外 O(1) 的算是不可能的,这个问题是大难题, 我就知道有人专门写博士论文算 Fib mod n 的周期。
这个范围使你的计算机不能模拟整个过程了,所以——思考新的算法吧。
2008/5/13 鋆邓 <tdzl...@gmail.com>:
> 没人回帖了,不好玩......
> > 这个范围使你的计算机不能模拟整个过程了,所以----思考新的算法吧。
这个范围使你的计算机不能模拟整个过程了,所以——思考新的算法吧。
8、再来一题,让你们知道矩阵不仅仅是矩阵,它不是一个人在战斗!
有一种k-电路矩阵,它有k个输入和k个输出,输入和输出都只有两种状态:高电位或低电位,输出和输出布成一个k*k的二极管矩阵,电子二极管的状态可
以通过激光设置,也具有两种状态:通过与不通过。
换言之,每个输出和输入当中的某些相通。如果所有与它连通的输入中存在一个高电位,那么输出为高电位。如果所有与它连通的输入全部为低电位,则输出低电
位。
现在,将N块相通k-电路矩阵一个接一个拼接成一串,每块电路的输入按照顺序连接到下一块电路板上。
现在,给定k个输入源的输入状态,求出最终一块电路板的k个输出的状态。
k不超过100,而N不超过2的32次方。
2008/5/5 天地之灵 <tdzl...@gmail.com>:矩阵也疯狂(天地之灵收集整理)
这个范围使你的计算机不能模拟整个过程了,所以----思考新的算法吧。
10、第二道调剂的题目:
有2N张牌,编号从1到2N,现在开始洗牌,每次将牌从中间分成两堆,将前一半依次插入偶数位置,后一半依次插入奇数位置
比如N = 3时,一次操作后得到:
1 2 3 4 5 6
4 1 5 2 6 3
接下来继续这个操作,得到
2 4 6 1 3 5
1 2 3 4 5 6
我们会看到3次操作之后,所有的牌回到了原来位置。
现在,请你用一个期望复杂度在O(N)以内的算法,对于给定的N,求出多少次洗牌操作之后,所有的牌都回到了原来的位置。
并且,请尝试证明一下你的复杂度在O(N)以内。
1、
我们分析 F(N) = F(N-1)+F(N-2),这是一个显然的线性递推问题。
如果我们将F(N)和F(N-1)组成向量A(n) =( F(N), F(N-1) )
那么就有
F(N+1) = 1* F(N) + 1*F(N-1)
F(N) = 1*F(N) + 0*F(N-1)
A(n+1) = ( F(N)+F(N-1), F(N) )
= A(n) *B
其中B = 1 1
1 0
那么,设A(0) = (F(1), F(0))
则有A(N) = A(0) * B^N
F(N) = (A(0) * B^N) [1] (其中[1]指取出该向量的第二项,这里用了C语言的思维理解向量和矩阵)
= F(1) * ((B^N)[1][0] + F(0) * ((B^N)[1][1])
对于求B^N,我们有lgN的算法来求矩阵的幂。并且,整个运算过程中没有减法和除法,因此我们可以在运算过程中将所有的加法当作模加来计算,所有乘法当作模乘来计算。
还有很多运用这种方法的场合,参见后面各题的解题报告。
至于你说的f[n] = sigma(c[i]*f[i]),对于c[i]不是很规律,并且无限的话,反而无法运用矩阵方法来解
矩阵所能解的是有限线性递推式问题。
对于无限的,比如说:每一个数是之前"所有"数的和,加上之前一个数的两倍,
那么针对f(n)是无法列出有限线性递推式的,但引入s(n)=sigma(f(n)),可以有:
s(n) = s(n-1)+f(n)
f(n) = s(n-1) + 2*f(n-1)
这样得到一个有限的递推式,才可以用矩阵来解决。
就是插不上嘴……
2008/5/29 hayate <haya...@gmail.com>:
--
新的理论从少数人的主张到一统天下,并不是因为这个理论说服了别人抛弃旧观点,而是因为一代人的逝去。
My blog: http://googollee.blog.163.com