题目
有一架天平,砝码的种类和个数要你来设计。给定一个整数n,则待称重的物品的重量可能是 [1,n] 之间的整数,砝码可以放在左盘也可以放在右盘,要能称出所有 [1,n] 重量的物品,请问如何设计砝码的种类和个数,使得这一套砝码的总个数最少?比如 n=3 时,至少要 2 个砝码才能称出所有重量为 1,2,3 物品。 n 的范围是 n⩽10**18
题目分析
首先拿到这一题时到底该有什么思路呢?
潜意识里可能是想着给一个N,然后我把这个N给爆搜一下,找出所有可能的结果,但是这是不行的 n⩽10**18 数据量太大。
那我换一种思路,就是:
如果我就给你1个砝码,那你最大能够称出来满足[1,n1]的这个n1是多少呢?
如果我就给你2个砝码,那你最大能够称出来满足[1,n2]的这个n2是多少呢?
如果我就给你3个砝码,那你最大能够称出来满足[1,n3]的这个n3是多少呢?
好,接下来我们在草稿纸上算一下:
-
只有1个砝码,那我能够称出来的最大连续重量就是1,砝码的重量也是1
-
那我们现在在1个砝码的基础上,再增加1个砝码,变成2个砝码,那这增加的砝码的重量应该是多少才合适啊,那我们不知道呀,那就先设为x吧。
不过我们知道1,x重量的砝码它能够称的最大重量就是x+1呀,那第二大重量就是x呀,第三大重量就是x-1呀。而且我们知道如果只有2个砝码,它能够称重的最大范围是[1,2,3,4],这样就可以得到第三大重量x-1=2,那x=3。第2个砝码的重量是3。
-
同理如果在两个砝码的基础上,我再增加一个砝码,这个砝码的重量仍然设为x,那就有:
3个砝码的重量依次是1,3,9 。能够表示的最大重量范围是:[1,13] -
这样我们就总结出规律了:
4个砝码的话应该在1,3,9的基础上增加的砝码重量是:x-(1+3+9)=13+1,x=27
-
通过上面的分析我们就可以知道,砝码的数量一旦给定,它能够称重的最大的连续重量也就确定了,而此时砝码的数量就是需要的最少的砝码的数量。比如1个砝码能够称重的最大连续重量是1,两个砝码能够称重的最大连续重量是4。所以对于给定重量的n,我们只需要确定这个n是在称重范围中的哪一个间隔中,就可以确定这个n需要的最少砝码数量了。
代码
"""
固有思维是给一个N,我把这个N给爆搜一下,找出所有可能的结果,但是这是不行的
我们应该换一种思维,就是:
从一开始连续,
如果我只给你一个砝码,那你最大能够称出来的重量是多少啊
如果我只给你2个砝码,那你最大能够称出来的重量又是多少啊
如果我只给你三个砝码呢
...
"""
"""
新加的砝码的重量按照3**n次方增长可以使连续称重的值达到最大化
能够将称重的最大重量是1+3+9+...+3**n-1,满足等比数列求和公式
"""
"""
依次计算出有1个砝码时能够称重的最大重量,有2个砝码时能够计算出的最大重量,...
如果刚好满足N <= 最大重量 说明此时的砝码数量是最少的砝码数量
"""
N = int(input())
n = 1
while True:
a1 = 1
an = 3 ** (n - 1)
q = 3
maxWeight = (an * q - a1) / (q - 1) # 等比数列求和公式
if N <= maxWeight:
print(n)
break
n += 1
参考链接
https://zhuanlan.zhihu.com/p/37895166