我们可以先求出每个数从0开始通过+1和×2操作得到目标值的最少操作次数。具体地,从目标值逆向操作:如果是奇数则减1,如果是偶数则除以2,直到0,操作次数即为该数所需的最少操作次数(也等于二进制中1的个数加上最高位的位置)。
由于每次操作可以选择一个区间,区间内的每个数可以独立选择+1或×2,我们可以将不同位置的相同操作进行合并。假设第i个数需要cnt_i次操作,第i+1个数需要cnt_{i+1}次操作。如果cnt_{i+1} > cnt_i,那么第i+1个数需要比第i个数多cnt_{i+1} - cnt_i次操作,这部分操作无法被共享,需要额外进行;如果cnt_{i+1} <= cnt_i,则第i+1个数的所有操作都可以与前面的操作共享,无需额外操作。因此,最少的总操作次数就是相邻操作次数的正向差值之和,即 ans = Σ max(0, cnt_i - cnt_{i-1}),其中cnt_0 = 0。
Java
在算法实验室中,你获得了一个初始全为 0 且长度为 n 的序列 a1,a2,…,an。你可以进行任意次操作,每次操作可以选定一个区间 [l,r](1≤l≤r≤n),对于每个 i∈[l,r],你必须独立地选择以下两种操作之一执行:
你的目标是将序列变成给定的目标序列 b1,b2,…,bn。请求出最少需要多少次操作。
约束条件:
Scan the QR code below with WeChat to sign in
First-time scan will create your account automatically
请使用微信扫描下方二维码完成注册