最简单版本:
#include <iostream>
#include <cmath>
using namespace std;
int main() {
int k;
cin >> k;
cout << ceil(log(2*k+1)/log(3)) << endl;
}
若有n个砝码 可以最多可连续表示出 0~k 时
只要选第n+1个砝码重量为2k+1
那么
k+1 可以用(2k+1) - (k-0) 表示
k+2 可以用(2k+1) - (k-1) 表示
…
2k+1 可以用(2k+1) - (0) 表示
2k+2 可以用(2k+1) + (1) 表示
…
3k+1 可以用(2k+1) + (k) 表示
这样n+1个砝码可以表示出0~3k+1
然后可以根据这个max[i+1] = 3*max[i]+1
然后运用数学知识转化为一个公式即可
大佬太强了%%%%
最后关于利用数学知识转化部分,这里略微做点补充吧233333
$f[i]$ 表示仅用 $i$ 个砝码时,能够表示出的最大区间为 $[1, f[i]]$。
由上面大佬的公式:$f[i] = 3 \times f[i - 1] + 1$ ,我们往下写
$$ f[i] = 3 \times f[i - 1] + 1 $$
$$ f[i] = 3 \times (3 \times f[i - 2] + 1) + 1 $$
$$ f[i] = 3 \times (3 \times (3 \times f[i - 3] + 1) + 1) + 1 $$
$$ \dots $$
容易看出,上面是秦九韶算法的形式,我们可以转化成等比数列的形式:
$$ f[i] = 3^{n - 1}f[1] + 3^{n - 2} + 3^{n - 3} + \dots + 3^1 + 3^0 $$
其中,$f[1] = 1$ 。于是,根据等比公式有:
$$ f[i] = \frac{3^0(3^n - 1)}{3 - 1} = \frac{3^n - 1}{2} $$
令 $y = f[i]$ ,我们有:
$$ n = \lceil log_3(2y + 1) \rceil $$
对应题意,这里的 $y$ 为 要表示的重量的范围上限 ,$n$ 即为所需的最少砝码个数。由于 $n$ 为整数,因此对结果我们需要向上取整。上取整公式为 $L = \lceil \frac{n}{k} \rceil = \frac{n + k - 1}{k}$ ,也可以直接使用
ceil()
函数。由于库函数自带的
log()
函数是以 $10$ 为底的,因此我们需要做点小转换$$ n =\lceil \frac{log_{10}(2y+1)}{log_{10}3} \rceil $$
不必用秦九韶,待定系数就行
f(n) = 3f(n - 1) + 1
f(n) + 0.5 = 3[f(n - 1) + 0.5]
哈哈哈,经典的高中数列问题。梦回高中啊
<<运用数学知识>> 原来我是fw🤡
算法?算术!
厉害大佬
,膜
orz
握草,orz
acwinger最喜欢的一句话: 啊?
这么怎么想到的呀,我太菜了
感觉没啥可说的了,膜
%%%
cout后面那个是怎么推的呀T—T,我数学小辣鸡
太强了
解释一下咋想的呗
前n个可以表示0~k;
第n+1个为x(x>k);
最大可测maxn=k+x;
第n+1个和前n个放两边可测得x-k;
让x-k=k+1,x=2k+1;
maxn=3k+1;
卧槽,太牛了
膜拜膜拜
最后
可以转化为
$$1 + 3 ^1^ + 3 ^2^ + 3 ^3^ + .....+ 3 ^ (n - 1)$$
等比式子转化为
$$ 1 - 3 ^n^ / 1 - 3 $$
然后化简成
1 - 3 ^n^ = -2 * n
2 * n + 1 = 3 ^ n
这鸡巴lateX
那个加一就不管了吗
管
比如说当前集合是
(1+3+3^2)
乘三加一就是
1+3*(1+3+3^2)
就变成等比数列了
不懂 我是笨蛋
max[i+1] = 3*max[i]+1 这个是什么意思
个人认为max[i]代表的是用了i个砝码所能表示最大的数(1~max[i]),希望能帮助到你。
感觉应该是个递推式
最后的3k + 1 可以作为下一项的(0 - k)
可以作为下一项的(0 ~k) , 下一项就选择(3k + 1) * 2 + 1
然后递推吧。
这个思想很妙啊,比求log(n) / log(2)可好多了啊
建议把数学递推式写一遍啊,我觉得还是很多没讲啊