找到从 x 到 y 的最小操作
Posted
技术标签:
【中文标题】找到从 x 到 y 的最小操作【英文标题】:finding the minimum operations to get from x to y 【发布时间】:2021-07-28 14:45:19 【问题描述】:仍在为递归而苦苦挣扎。 我有一个代码应该让我的操作量最少,以便从 x 到 y。 只需乘以 2 或加 +1 例如从 7 到 12 ......它的 5 次操作,因为您需要 +1 五次。 我的代码对我来说不能正常工作,我无法弄清楚我缺少什么才能让它正确。
public static int minOps(int x,int y)
if (x >= y) return 0;
int add = 1 + minOps(x + 1, y);
int mul = 1 + minOps(x * 2, y);
return Math.min(add, mul);
【问题讨论】:
【参考方案1】:您没有考虑到超调是不合法的,因此返回0
是不正确的。只需在基本情况下更改以下内容
if(x > y) return Integer.MAX_VALUE;
if(x == y) return 0;
【讨论】:
请注意,返回Integer.MAX_VALUE
会导致在结果中加1 时溢出到Integer.MIN_VALUE
,这就是最小值。
另外,尝试探索 DP。您可以通过记住已经计算结果的值来使用 memoization 来提高运行时间
@AndyTurner 你是对的。对于具有较大值的情况,OP 应在调用递归之前进行检查。对于其他情况,我认为这应该可以正常工作
好的,但添加它只会在我每次运行程序时给我 MAX_VALUE。
嗯,不,这不仅仅是“大值”:当其中一个超调时,您在这里的建议会导致错误的答案,因为超调是最小值。【参考方案2】:
@arjunkhera's answer 有一个正确的想法——当你超过时返回一个“可怕”的结果,所以你永远不要选择它——但需要在结果中加 1 时避免潜在的溢出:
public static int minOps(int x,int y)
// Return 1 less that MAX_VALUE, so adding 1 doesn't overflow.
// You'll never get as far as here anyway, your stack will overflow long
// before, so subtracting 1 makes no practical difference.
if (x > y) return Integer.MAX_VALUE - 1;
if (x >= y) return 0;
int add = 1 + minOps(x + 1, y);
int mul = 1 + minOps(x * 2, y);
return Math.min(add, mul);
或者,您可以推迟添加 1:
if (x > y) return Integer.MAX_VALUE;
if (x >= y) return 0;
int add = minOps(x + 1, y);
int mul = minOps(x * 2, y);
return 1 + Math.min(add, mul);
因为add
和mul
中的至少一个不等于MAX_VALUE
。
【讨论】:
以上是关于找到从 x 到 y 的最小操作的主要内容,如果未能解决你的问题,请参考以下文章
CodeForces 19D Points(离散化+线段树+单点更新)
2022-06-06:大妈一开始手上有x个鸡蛋,她想让手上的鸡蛋数量变成y, 操作1 : 从仓库里拿出1个鸡蛋到手上,x变成x+1个, 操作2 : 如果手上的鸡蛋数量是3的整数倍,大妈可以直接把三分之
Codeforces 455C Civilization:树的直径 + 并查集合并树后直径最小