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,… 可以是加、减、乘、除之一
例如,对于 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))
}
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));
}
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;
}
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,… 可以是加、减、乘、除之一 例如的更多相关文章
- 输入一个数字n 如果n为偶数则除以2,若为奇数则加1或者减1,直到n为1,求最少次数 写出一个函数
题目: 输入一个数字n 如果n为偶数则除以2,若为奇数则加1或者减1,直到n为1,求最少次数 写出一个函数 首先,这道题肯定可以用动态规划来解, n为整数时,n的解为 n/2 的解加1 n为奇数时 ...
- java————数组 简单写出一个管理系统
数组的特点 1, 数组是一块连续的空间,下标描述空间的位置. 2, 下标从0开始,最大下标为数组长度—1.(*.length-1) 3, 数组元素都是变量.(就是每个下标对应的内容).变量的类型 ...
- 如何写出一个让人很难发现的bug?
程序员的日常三件事:写bug.改bug.背锅.连程序员都自我调侃道,为什么每天都在加班?因为我的眼里常含bug. 那么如何写出一个让(坑)人(王)很(之)难(王)发现的bug呢? - 1 -新手开发+ ...
- 浅谈如何写出一个让(坑)人(王)很(之)难(王)发现的bug
该文章内容来自脚本之家,原文链接:https://www.jb51.net/news/598404.html 程序员的日常三件事:写bug.改bug.背锅.连程序员都自我调侃道,为什么每天都在加班?因 ...
- 请写出一个超链接,点击链接后可以向zhangsan@d-heaven.com发送电子邮件。
请写出一个超链接,点击链接后可以向zhangsan@d-heaven.com发送电子邮件. <a href=”mailto: zhangsan@d-heaven.com”>发邮件</ ...
- 2019-8-31-C#-如何写出一个不能被其他程序集继承的抽象类
title author date CreateTime categories C# 如何写出一个不能被其他程序集继承的抽象类 lindexi 2019-08-31 16:55:58 +0800 20 ...
- JS函数 编程练习 使用javascript代码写出一个函数:实现传入两个整数后弹出较大的整数。
编程练习 使用javascript代码写出一个函数:实现传入两个整数后弹出较大的整数. 任务 第一步: 编写代码完成一个函数的定义吧. 第二步: 我们来补充函数体中的控制语句,完成函数功能吧. 提示: ...
- C# 如何写出一个不能被其他程序集继承的抽象类
我需要限定某个抽象类只能在我程序集类实现,而不支持其他程序集实现,也就是我需要一个不能被继承的抽象类 在 C# 里面有抽象类和接口,这两个都是期望被继承才能被使用,而抽象类是可以做到只能在自己程序集和 ...
- 用js写出一个漂亮的单选框选中效果
一般的input框比较简单,我们可以用JavaScript配合css背景图片定位让我们模拟写出一个点击选中效果 首先需要有个图片素材,当页面加载的时候是背景图片定位到左图,当我们点击图片的时候,背景图 ...
- 【C++】从零开始的CS:GO逆向分析3——写出一个透视
[C++]从零开始的CS:GO逆向分析3--写出一个透视 本篇内容包括: 1. 透视实现的方法介绍 2. 通过进程名获取进程id和进程句柄 3. 通过进程id获取进程中的模块信息(模块大小,模块地址, ...
随机推荐
- Java方法的定义
前言 经过前面两篇关于面向对象.类和对象的文章,壹哥相信你现在对面向对象已经有了基本的了解.我们知道,在一个类中,包括属性和行为两大核心要素.我们之前已经给大家讲解了如何定义属性,但很多同学对方法还不 ...
- 处理尚不存在的 DOM 节点
探索 MutationObserver API 与传统轮询等待最终被创建的节点方法相比的优劣. 有时候,您需要操作尚未存在的 DOM 的某个部分. 出现这种需求的原因有很多,但你最常看到的是在处理第三 ...
- Java (强/弱/软/虚)引用
一.整体架构
- Auto Photoshop StableDiffusion - 这是一款可以在 Photoshop 中使用 AI 智能 Automatic1111 进行插画、海报等设计的插件
简介 Auto Photoshop StableDiffusion - 这是一款可以在 Photoshop 中使用 AI 智能 Automatic1111 进行插画.海报等设计的插件,此插件可以是你在 ...
- 阿里巴巴为什么这样强制从List中删除元素
还是先举个例子,你侄女对天文知识感兴趣,然后你就用程序写了太阳系九大星系(水星.金星.地球.火星.木星.土星.天王星.海王星.冥王星)的运行轨迹图,然后拿给侄女看.然后她说错了错了,你的知识太旧了,多 ...
- 数据文件的读写—R实现
数据文件的读写 在R语言中可以读写的最基本的数据格式就是text,以及csv文件.用read.table()或者read.csv函数就可以,相应的写入函数是write.table(),write.cs ...
- 二进制安装Kubernetes(k8s) v1.23.6
二进制安装Kubernetes(k8s) v1.23.6 背景 kubernetes二进制安装 1.23.3 和 1.23.4 和 1.23.5 和 1.23.6 文档以及安装包已生成. 后续尽可能第 ...
- 迁移学习《Pseudo-Label : The Simple and Efficient Semi-Supervised Learning Method for Deep Neural Networks》
论文信息 论文标题:Pseudo-Label : The Simple and Efficient Semi-Supervised Learning Method for Deep Neural Ne ...
- 数据泵:oracle数据泵导入导出部分用户
问题描述:需要将140服务器中的tbomnew实例下的部分用户导入到118服务器下的tbompx实例中,本次导入导出的两个数据库均为19C 部分用户名:CORE,MSTDATA,BOMMGMT,CFG ...
- Nuxtjs实现服务端渲染和静态化站点
本文将介绍如何使用Nuxtjs对vue项目进行ssr和静态化处理. Nuxtjs简单介绍 首先,我们简单了解下Nuxtjs框架,Nuxt.js是一个基于Vue的通用框架,主要用于解决Vue项目的服务端 ...