LeetCode //C - 964. Least Operators to Express Number

964. Least Operators to Express Number

Given a single positive integer x, we will write an expression of the form x (op1) x (op2) x (op3) x ... where each operator op1, op2, etc. is either addition, subtraction, multiplication, or division (+, -, *, or /). For example, with x = 3, we might write 3 * 3 / 3 + 3 - 3 which is a value of 3.

When writing such an expression, we adhere to the following conventions:

  • The division operator (/) returns rational numbers.
  • There are no parentheses placed anywhere.
  • We use the usual order of operations: multiplication and division happen before addition and subtraction.
  • It is not allowed to use the unary negation operator (-). For example, "x - x" is a valid expression as it only uses subtraction, but "-x + x" is not because it uses negation.

We would like to write an expression with the least number of operators such that the expression equals the given target. Return the least number of operators used.

Example 1:

Input: x = 3, target = 19
Output: 5
Explanation: 3 * 3 + 3 * 3 + 3 / 3.

The expression contains 5 operations.

Example 2:

Input: x = 5, target = 501
Output: 8
Explanation: 5 * 5 * 5 * 5 - 5 * 5 * 5 + 5 / 5.

The expression contains 8 operations.

Example 3:

Input: x = 100, target = 100000000
Output: 3
Explanation: 100 * 100 * 100 * 100.

The expression contains 3 operations.

Constraints:
  • 2 <= x <= 100
  • 1 < = t a r g e t < = 2 ∗ 10 8 1 <= target <= 2 * 10^8 1<=target<=2∗108

From: LeetCode

Link: 964. Least Operators to Express Number


Solution:

Ideas:
  • For small values v <= x, directly compute the best using only 1s (x/x) or as x minus some 1s.

  • For larger values, find the closest power x^k and try:

    • Undershoot: use x^(k-1) and build the remainder.
    • Overshoot: use x^k and subtract the difference (only if it helps).
  • Use memoization to avoid recomputing subproblems.

Code:
c 复制代码
typedef struct {
    int key;
    int val;
} Pair;

static Pair memo[10000];
static int memoSize;

static int dfs(int x, int v) {
    // Base case: v <= x
    if (v <= x) {
        // Option 1: v = 1 + 1 + ... + 1 (v times)
        //   1 is x / x  -> 1 operator
        //   plus (v - 1) additions
        //   total = v (division) + (v - 1) (+) = 2*v - 1
        int op_add = 2 * v - 1;

        // Option 2: v = x - ( (x - v) ones )
        //   (x - v) ones: 2*(x - v) - 1 operators
        //   one more '-' to subtract from x
        //   total = 2*(x - v)
        int op_sub = 2 * (x - v);

        return op_add < op_sub ? op_add : op_sub;
    }

    // Check memo
    for (int i = 0; i < memoSize; ++i) {
        if (memo[i].key == v) return memo[i].val;
    }

    // Find smallest k such that x^k >= v
    int k = 2;
    long y = (long)x * x;   // y = x^2 initially
    while (y < v) {
        y *= x;
        ++k;               // now y = x^k
    }
    // Now y = x^k >= v, and y/x = x^(k-1)

    // Option 1 (undershoot):
    //   Use x^(k-1) once (cost k-1 multiplications),
    //   then express the remaining (v - x^(k-1))
    int op1 = (k - 1) + dfs(x, v - (int)(y / x));

    int ans = op1;

    // Option 2 (overshoot), only if the "over" part is smaller than v:
    //   Use x^k once (cost k multiplications),
    //   then express (x^k - v), and subtract it.
    if (y - v < v) {
        int op2 = k + dfs(x, (int)(y - v));
        if (op2 < ans) ans = op2;
    }

    // Save to memo
    memo[memoSize].key = v;
    memo[memoSize].val = ans;
    ++memoSize;

    return ans;
}

int leastOpsExpressTarget(int x, int target) {
    memoSize = 0;  // reset memo for each test case
    return dfs(x, target);
}
相关推荐
郝学胜-神的一滴1 小时前
Effective Modern C++ 条款40:深入理解 Atomic 与 Volatile 的多线程语义
开发语言·c++·学习·算法·设计模式·架构
摸鱼仙人~1 小时前
算法题避坑指南:数组/循环范围的 `+1` 到底什么时候加?
算法
liliangcsdn2 小时前
基于似然比的显著图可解释性方法的探索
人工智能·算法·机器学习
骇城迷影2 小时前
代码随想录:二叉树篇(中)
数据结构·c++·算法·leetcode
期末考复习中,蓝桥杯都没时间学了2 小时前
力扣刷题23
算法·leetcode·职场和发展
菜鸡儿齐2 小时前
leetcode-子集
算法·leetcode·深度优先
今儿敲了吗2 小时前
28| A-B数对
数据结构·c++·笔记·学习·算法
Desirediscipline2 小时前
#include<limits>#include <string>#include <sstream>#include <iomanip>
java·开发语言·前端·javascript·算法
Felven2 小时前
B. Luntik and Subsequences
算法