964. Least Operators to Express Number

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zjucor/article/details/85221526

Given a single positive integer x, we will write an expression of the form x (op1) x (op2) x (op3) x ... where each operator op1op2, 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:

  1. The division operator (/) returns rational numbers.
  2. There are no parentheses placed anywhere.
  3. We use the usual order of operations: multiplication and division happens before addition and subtraction.
  4. It's 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 expressions 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.

 

Note:

  • 2 <= x <= 100
  • 1 <= target <= 2 * 10^8

思路:

1一定是通过x/x得到,然后剩下的部分一定是x的倍数,所以比赛的时候一直想的是划分成若干层,比如x = 3, target = 19:先求6+1,因为3*6+1=19,但是随着层数的嵌套,实际用了多少符号变得不好求了。

Discuss里的答案:独立考虑每个x的次幂使用的个数。具体来说:

求出x的整数次幂数组(一直求到比target大的那个数)A,然后从后往前考虑A,每次考虑用不用当前这个A[i],假设还剩下left需要求出来,那就可以有left/A[i]个A[i],或者(left/A[i])+1个A[i](超过left用减法)

注意:对于每个次幂,前面会加一个符号,比如用3*3*3的时候,在算的时候用的是+3*3*3或者-3*3*3;然而最后算完之后要把前面那个多余的符号去掉,对应 elif y == 0:return -1 这样代码

import functools
import math
class Solution(object):
    @functools.lru_cache(None)
    def leastOpsExpressTarget(self, x, y):
        """
        :type x: int
        :type target: int
        :rtype: int
        """
        k = int(math.log(y, x)) + 1
        def dfs(y, k):
            if k == 0:  return y + y - 1
            elif y == 0:return -1
            need, left = divmod(y, x**k)
            return min(dfs(left, k - 1) + need * k, dfs(x**k - left, k - 1) + (need + 1) * k)
        return dfs(y, k)
    
s=Solution()
print(s.leastOpsExpressTarget(x = 3, y = 19))
import math
class Solution(object):
    def leastOpsExpressTarget(self, x, y):
        """
        :type x: int
        :type target: int
        :rtype: int
        """
        k = int(math.log(y, x)) + 1
        memo = {}
        def dfs(y, k):
            if (y,k) in memo: return memo[(y,k)]
            if k == 0:  return y + y - 1
            elif y == 0:return -1
            need, left = divmod(y, x**k)
            res = min(dfs(left, k - 1) + need * k, dfs(x**k - left, k - 1) + (need + 1) * k)
            memo[(y,k)] = res
            return res
        return dfs(y, k)
    
s=Solution()
print(s.leastOpsExpressTarget(x = 3, y = 19))

有了memo的形式,也可以换成DP

猜你喜欢

转载自blog.csdn.net/zjucor/article/details/85221526