外企程序员一枚,在金融公司打工,头衔高大上,常年995,做着最底层的苦力。每天的工作就是Ctrl+C Ctrl+V 。平时除了开发代码,还要配置很多重复的脚本规则。
某日,在工作之余突发奇想,如果初始是1条记录,我需要复制粘贴多少次,才能拷贝100条记录。
比如:
初始一条记录: 假设拷贝1次2s ,粘贴1次1s,众所周知,拷贝1次,可以粘贴无限次,因此拷贝生成100条记录。可以如下:
拷贝操作 | 粘贴操作 | 生成记录数 | 耗时 | |
---|---|---|---|---|
第一轮 | 1次 | 4次 | 5条 | 2+4=6s |
第二轮 | 1次 | 4次 | 5+4*5=25条 | 6+6=12s |
第三轮 | 1次 | 3次 | 25+25*3=100条 | 12+2+3=17s |
当然也可以拷贝一次,粘贴99次,这样就需要2+99=101秒
于是我脑海前生成一个疑惑,如果记录数是N,怎样计算出需要的最短时长?
从上面的表格里其实可以理解,我们可以整个过程切割成n次循环,且每次循环只需要copy 1次,粘贴Xi次。因此上面的式子可以转换为下面问题。
对于上面的数学模型,相信大家很难求解,因为只有一个不等式,n+1个变量,需要求n+1个变量的最小值。
于是我想到化简当前方程式,这里我可以设Xi 中,存在3个不同的值,a,b,c,满足a<b<c, 取m=min(b-a,c-a),则 abc <=(a+m)b(c-m),这里暂且不求证了,把式子展看就能计算出来。
所以对于同样的耗时,如果 a+m, b, c-m 的序列比 a,b,c 能算出更大的值,因此可知
因为如果有两个值X,Y,他们的|Y-X| >1,那必然比X+1,Y-1计算得到的乘积要小。
这里我利用python遍历求解,代码如下:
import math
def getMinSecond(N):
minSecond=2**32
for x in range(1,8):
maxN=math.ceil(math.log(N,x+1))
minN=math.ceil(math.log(N,x+2))-1
for n in range(minN,maxN+1):
for z in range(0,n+1):
calN=((x+1)**(n-z))*((x+2)**z)
if calN>N:
minSecond=min(minSecond,n*x+z+2*n)
return minSecond
计算出的结果如下:
记录数 (N) | 需要时间 (秒) | 因式分解 |
---|---|---|
12 | 9 | 3*4 |
16 | 10 | 4*4 |
20 | 11 | 4*5 |
27 | 12 | 3*3*3 |
36 | 13 | 3*3*4 |
48 | 14 | 3*4*4 |
64 | 15 | 4*4*4 |
81 | 16 | 3*3*3*3 |
108 | 17 | 3*3*3*4 |
144 | 18 | 3*3*4*4 |
192 | 19 | 3*4*4*4 |
256 | 20 | 4*4*4*4 |
324 | 21 | …… |
432 | 22 | |
576 | 23 | |
768 | 24 | |
1024 | 25 | |
1296 | 26 | |
1728 | 27 | |
2304 | 28 | |
3072 | 29 | |
4096 | 30 | |
5184 | 31 | |
6912 | 32 | |
9216 | 33 |
可以发现,从20开始,每次copy后粘贴3~4次是最优解.
因此,代入x=3 p=n, q=z
未完待续……