首页 > 其他分享 >2023-05-25:给定一个正整数 x,我们将会写出一个形如 x (op1) x (op2) x (op3) x ... 的表达式 其中每个运算符 op1,op2,… 可以是加、减、乘、除之一 例如

2023-05-25:给定一个正整数 x,我们将会写出一个形如 x (op1) x (op2) x (op3) x ... 的表达式 其中每个运算符 op1,op2,… 可以是加、减、乘、除之一 例如

时间:2023-05-25 21:33:09浏览次数:57  
标签:op1 op2 int 运算符 dpf cost ans dp target

2023-05-25:给定一个正整数 x,我们将会写出一个形如 x (op1) x (op2) x (op3) x ... 的表达式

其中每个运算符 op1,op2,… 可以是加、减、乘、除之一

例如,对于 x = 3,我们可以写出表达式 3 * 3 / 3 + 3 - 3,该式的值为3

在写这样的表达式时,我们需要遵守下面的惯例:

除运算符(/)返回有理数

任何地方都没有括号

我们使用通常的操作顺序:乘法和除法发生在加法和减法之前

不允许使用一元否定运算符(-)。例如,“x - x” 是一个有效的表达

因为它只使用减法,但是 “-x + x” 不是,因为它使用了否定运算符

我们希望编写一个能使表达式等于给定的目标值 target 且运算符最少的表达式。

返回所用运算符的最少数量。

输入:x = 5, target = 501。

输出:8。

答案2023-05-25:

大体过程如下:

1.定义函数 leastOpsExpressTarget,传入参数 x 和 target。

2.初始化一个 map 类型的变量 dp,用于记录已经计算过的结果。

3.调用函数 dpf,传入参数 0、target、x 和 dp。函数 dpf 的作用是计算在当前情况下,target 最少需要几个运算符才能被表达出来。

4.在函数 dpf 中,首先判断当前情况是否已经计算过,如果已经计算过则直接返回结果。

5.如果没有计算过,则根据题目要求,最多只能使用 x 的 i 次方来进行运算,所以需要记录当前来到了 x 的 i 次方这个数字。

6.如果 target 大于 0 且 i 小于 39(为了防止溢出),则根据题目要求,将 target 分解成商和余数两部分,然后分别计算用加、减、乘、除运算符可以得到的最小的运算次数。

7.最后,将计算出的结果保存到 dp 中,并返回该结果。

8.定义函数 cost,传入参数 i,用于得到 x 的 i 次方这个数字需要几个运算符,默认前面再加个'+'或'-'。

9.定义函数 min,传入参数 a 和 b,用于比较 a 和 b 的大小,并返回较小的值。

10.在主函数 main 中,定义变量 x 和 target,分别赋值为 5 和 501。然后调用函数 leastOpsExpressTarget,并将结果输出。

时间复杂度:

  • 函数 leastOpsExpressTarget 中调用了函数 dpf,而函数 dpf 的时间复杂度为 O(log(target))(因为 i 最大可以达到 39,x^39 已经大于等于 target),所以最终的时间复杂度为 O(log(target))。

空间复杂度:

  • 函数 leastOpsExpressTarget 中创建了一个 map 类型的变量 dp,其中存储的元素个数最多为 O(log(target) * 40),所以空间复杂度为 O(log(target))。

go完整代码如下:

package main

import (
	"fmt"
)

func leastOpsExpressTarget(x, target int) int {
	dp := make(map[int]map[int]int)
	return dpf(0, target, x, dp) - 1
}

// i : 当前来到了x的i次方
// target : 认为target只能由x的i次方,或者更高次方来解决,不能使用更低次方!
// 返回在这样的情况下,target最少能由几个运算符搞定!
// (3, 1001231) -> 返回值!
// dp.get(3) -> {1001231 对应的value}
func dpf(i, target, x int, dp map[int]map[int]int) int {
	if val, ok := dp[i][target]; ok {
		return val
	}

	ans := 0
	if target > 0 && i < 39 {
		if target == 1 {
			ans = cost(i)
		} else {
			div := target / x
			mod := target % x
			p1 := mod*cost(i) + dpf(i+1, div, x, dp)
			p2 := (x-mod)*cost(i) + dpf(i+1, div+1, x, dp)
			ans = min(p1, p2)
		}
	}
	if _, ok := dp[i]; !ok {
		dp[i] = make(map[int]int)
	}
	dp[i][target] = ans
	return ans
}

// 得到x的i次方这个数字
// 需要几个运算符,默认前面再加个'+'或'-'
func cost(i int) int {
	if i == 0 {
		return 2
	}
	return i
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func main() {
	x := 5
	target := 501
	fmt.Println(leastOpsExpressTarget(x, target))
}

2023-05-25:给定一个正整数 x,我们将会写出一个形如 x (op1) x (op2) x (op3) x ... 的表达式 其中每个运算符 op1,op2,… 可以是加、减、乘、除之一 例如_运算符

rust完整代码如下:

use std::collections::HashMap;

fn least_ops_express_target(x: i32, target: i32) -> i32 {
    let mut dp: HashMap<i32, HashMap<i32, i32>> = HashMap::new();
    dpf(0, target, x, &mut dp) - 1
}

// i : 当前来到了x的i次方
// target : 认为target只能由x的i次方,或者更高次方来解决,不能使用更低次方!
// 返回在这样的情况下,target最少能由几个运算符搞定!
// (3, 1001231) -> 返回值!
// dp.get(3) -> {1001231 对应的value}
fn dpf(i: i32, target: i32, x: i32, dp: &mut HashMap<i32, HashMap<i32, i32>>) -> i32 {
    if let Some(map) = dp.get(&i) {
        if let Some(val) = map.get(&target) {
            return *val;
        }
    }

    let ans: i32;
    if target > 0 && i < 39 {
        if target == 1 {
            ans = cost(i);
        } else {
            let div = target / x;
            let mod0 = target % x;
            let p1 = mod0 * cost(i) + dpf(i + 1, div, x, dp);
            let p2 = (x - mod0) * cost(i) + dpf(i + 1, div + 1, x, dp);
            ans = p1.min(p2);
        }
    } else {
        ans = 0;
    }

    dp.entry(i).or_insert(HashMap::new()).insert(target, ans);
    ans
}

// 得到x的i次方这个数字
// 需要几个运算符,默认前面再加个'+'或'-'
fn cost(i: i32) -> i32 {
    if i == 0 {
        2
    } else {
        i
    }
}

fn main() {
    let x = 3;
    let target = 19;
    println!("{}", least_ops_express_target(x, target));

    let x = 5;
    let target = 501;
    println!("{}", least_ops_express_target(x, target));

    let x = 100;
    let target = 100000000;
    println!("{}", least_ops_express_target(x, target));
}

2023-05-25:给定一个正整数 x,我们将会写出一个形如 x (op1) x (op2) x (op3) x ... 的表达式 其中每个运算符 op1,op2,… 可以是加、减、乘、除之一 例如_时间复杂度_02

c语言完整代码如下:

#include <stdio.h>
#include <stdlib.h>

int leastOpsExpressTarget(int x, int target);
int cost(int i);

int dpf(int i, int target, int x, int*** dp) {
    if (dp[i][target] != 0) {
        return dp[i][target];
    }

    int ans = 0;
    if (target > 0 && i < 39) {
        if (target == 1) {
            ans = cost(i);
        }
        else {
            int div = target / x;
            int mod = target % x;
            int p1 = mod * cost(i) + dpf(i + 1, div, x, dp);
            int p2 = (x - mod) * cost(i) + dpf(i + 1, div + 1, x, dp);
            ans = p1 < p2 ? p1 : p2;
        }
    }
    dp[i][target] = ans;
    return ans;
}

int leastOpsExpressTarget(int x, int target) {
    int** dp = (int**)calloc(40, sizeof(int*));
    for (int i = 0; i < 40; ++i) {
        dp[i] = (int*)calloc(target + 1, sizeof(int));
    }
    int ans = dpf(0, target, x, dp) - 1;
    for (int i = 0; i < 40; ++i) {
        free(dp[i]);
    }
    free(dp);
    return ans;
}

// 得到x的i次方这个数字
// 需要几个运算符,默认前面再加个'+'或'-'
int cost(int i) {
    return i == 0 ? 2 : i;
}

int main() {
    int x = 5;
    int target = 501;
    printf("%d\n", leastOpsExpressTarget(x, target));
    return 0;
}

2023-05-25:给定一个正整数 x,我们将会写出一个形如 x (op1) x (op2) x (op3) x ... 的表达式 其中每个运算符 op1,op2,… 可以是加、减、乘、除之一 例如_运算符_03

c++完整代码如下:

#include <iostream>
#include <unordered_map>

using namespace std;

int cost(int i);

int dpf(int i, int target, int x, unordered_map<int, unordered_map<int, int>>& dp) {
    if (dp.count(i) && dp[i].count(target)) {
        return dp[i][target];
    }

    int ans = 0;
    if (target > 0 && i < 39) {
        if (target == 1) {
            ans = cost(i);
        }
        else {
            int div = target / x;
            int mod = target % x;
            int p1 = mod * cost(i) + dpf(i + 1, div, x, dp);
            int p2 = (x - mod) * cost(i) + dpf(i + 1, div + 1, x, dp);
            ans = min(p1, p2);
        }
    }
    if (!dp.count(i)) {
        dp[i] = unordered_map<int, int>();
    }
    dp[i][target] = ans;
    return ans;
}

int leastOpsExpressTarget(int x, int target) {
    unordered_map<int, unordered_map<int, int>> dp;
    return dpf(0, target, x, dp) - 1;
}

// 得到x的i次方这个数字
// 需要几个运算符,默认前面再加个'+'或'-'
int cost(int i) {
    return i == 0 ? 2 : i;
}

int main() {
    int x = 5;
    int target = 501;
    cout << leastOpsExpressTarget(x, target) << endl;
    return 0;
}

2023-05-25:给定一个正整数 x,我们将会写出一个形如 x (op1) x (op2) x (op3) x ... 的表达式 其中每个运算符 op1,op2,… 可以是加、减、乘、除之一 例如_运算符_04

标签:op1,op2,int,运算符,dpf,cost,ans,dp,target
From: https://blog.51cto.com/moonfdd/6351377

相关文章

  • 2023-05-25:给定一个正整数 x,我们将会写出一个形如 x (op1) x (op2) x (op3) x ... 的
    2023-05-25:给定一个正整数x,我们将会写出一个形如x(op1)x(op2)x(op3)x...的表达式其中每个运算符op1,op2,…可以是加、减、乘、除之一例如,对于x=3,我们可以写出表达式3*3/3+3-3,该式的值为3在写这样的表达式时,我们需要遵守下面的惯例:除运算符(/)返回有理数......
  • 【JavaScript用法】JavaScript(JS)的基本语法(JS数据类型,JS变量,JS运算符,JS流程控制语句
    JavaScript(JS)的基本语法目录JavaScript(JS)的基本语法一.与html结合方式二.注释三.数据类型:四.变量五.运算符(和Java有点类似)六.流程控制语句(和JAVA 类似):七.JS特殊语法:一.与html结合方式       1.内部JS:定义<script>,标签体内容就是js代码(可以理解为和html......
  • Pjudge #21680. 【PER #3】运算符 2
    一道很有教育意义的题目。首先我们有众所周知的AND卷积和XOR卷积,容易证明不同位互不干扰,拼起来可以获得\(1+4+5\)分的高分!接下来我们按照\(1\)的个数来讨论:\(0\)个\(1\):将这一位赋值为\(0\)即可。\(1\)个\(1\):如果形如0001那么就和AND卷积是一样的,那如果......
  • 海象运算符
    Python的海象运算符(WalrusOperator)是在Python3.8中引入的新特性海象运算符通常在以下几种情况下使用:循环条件判断:海象运算符可以在循环条件中方便地读取输入或函数的返回值,并进行比较。这样可以避免在循环体内重复调用函数或读取输入,提高代码的简洁性和可读性。while(line......
  • 【爬虫数据集】李子柒YouTube频道TOP10热门视频的TOP2000热门评论,共计2W条
    目录一、背景二、爬取目标三、结果展示四、演示视频五、附完整数据一、背景这段时间,有超多小伙伴找我要YouTube数据,做数据分析、情感分析之类的研究工作,但很多人并不是计算机软件相关专业,不具备爬虫开发技术,但又有数据需求,可能是新闻传播学、社会学等相关学科,旨在分析社会热点现......
  • js中 new 运算符的作用
    在JavaScript中,new运算符用于创建一个对象实例。它的作用是通过调用构造函数创建一个新的对象,并且将该对象作为上下文来执行构造函数,最后返回这个新创建的对象。使用new运算符的一般语法如下:letnewObj=newConstructor();其中,Constructor是一个构造函数,newObj是通过......
  • 作用域运算符
    目前已经学过了作用域运算符的两个作用1.调用类中静态成员函数classPerson{public:staticintm_person;};intmain(){Person::m_person;}2.类内用typedef或则using起类型别名,在类外使用该类型别名时:classPerson{public:usingpi=int;};int......
  • python之字符串和运算符
    python基本数据类型python之字符串和运算符字符串格式化字符串print(6+6)print('6'+'6')print('jerr'+'y')#print(6+'6')两个不同类型的相加会报一个类型错误1266jerry拼串s='hello'print('s='+s)用+号来进行拼串s=hello传递参数s=......
  • Python程序与用户交互&基本运算符
    一、用户交互1.输入input:关键字:input()-输入在python3中input关键字会等待用户的输入,用户输入任何内容,都存成字符串类型,然后赋值给等号左边的变量名在python2中存在一个raw_input功能与python3中的input功能一模一样在python2中还存在一个input功能,需要用户输入一个明......
  • 神策杯 2018高校算法大师赛(个人、top2、top6)方案总结
    1竞赛背景神策数据推荐系统是基于神策分析平台的智能推荐系统。它针对客户需求和业务特点,并基于神策分析采集的用户行为数据使用机器学习算法来进行咨询、视频、商品等进行个性化推荐,为客户提供不同场景下的智能应用,如优化产品体验,提升点击率等核心的业务指标。神策推荐系统是一......