2024-01-03:用go语言,给你两个长度为 n 下标从 0 开始的整数数组 cost 和 time,

分别表示给 n 堵不同的墙刷油漆需要的开销和时间。你有两名油漆匠,

一位需要 付费 的油漆匠,刷第 i 堵墙需要花费 time[i] 单位的时间,

开销为 cost[i] 单位的钱。

一位 免费 的油漆匠,刷 任意 一堵墙的时间为 1 单位,开销为 0,

但是必须在付费油漆匠 工作 时,免费油漆匠才会工作。

请你返回刷完 n 堵墙最少开销为多少?

输入:cost = [1,2,3,2], time = [1,2,3,2]。

输出:3。

来自力扣。2742. 给墙壁刷油漆。

答案2024-01-03:

来自左程云

灵捷3.5

大体过程如下:

paintWalls1 函数

1.paintWalls1 函数是基于递归方法的解决方案。

2.在 process1 函数中,通过递归方式将每种情况下的最小开销计算出来。

3.递归调用时考虑两种情况,选择当前墙刷或者不刷,计算出最小开销。

4.该方法在递归调用的过程中可能会有很多重复计算,效率可能不高。

paintWalls2 函数

1.paintWalls2 函数采用了记忆化搜索的方式。

2.定义了一个二维数组 dp 用于记录已经计算过的结果,避免重复计算。

3.通过递归+记忆化搜索的方式优化了重复计算,提高了效率。

paintWalls3 函数

1.paintWalls3 函数采用了动态规划的方式。

2.使用一个一维数组 dp 保存不同墙数下的最小开销。

3.结合循环和动态递推的方式,迭代计算每墙的最小开销,直到第 n 墙。

时间和空间复杂度

  • 时间复杂度:

    • paintWalls1 使用了递归,可能有大量重复计算,其时间复杂度为 O(2^n)。

    • paintWalls2paintWalls3 使用了记忆化搜索和动态规划,时间复杂度都为 O(n^2),其中 n 为墙的数量。

  • 空间复杂度:

    • paintWalls1paintWalls2 的额外空间复杂度为 O(n^2),因为它们都使用了二维数组存储中间结果。

    • paintWalls3 的额外空间复杂度为 O(n),因为它只用了一个一维数组保存中间结果。

go完整代码如下:

package main

import (
"fmt"
"math"
) // paintWalls1 represents the first function from the given Java code.
func paintWalls1(cost []int, time []int) int {
return process1(cost, time, 0, len(cost))
} // process1 is the recursive function as mentioned in the Java code.
func process1(cost []int, time []int, i int, s int) int {
if s <= 0 {
return 0
}
// s > 0
if i == len(cost) {
return math.MaxInt32
} else {
p1 := process1(cost, time, i+1, s)
p2 := math.MaxInt32
next2 := process1(cost, time, i+1, s-1-time[i])
if next2 != math.MaxInt32 {
p2 = cost[i] + next2
}
return int(math.Min(float64(p1), float64(p2)))
}
} // paintWalls2 is the second function from the given Java code.
func paintWalls2(cost []int, time []int) int {
n := len(cost)
dp := make([][]int, n+1)
for i := range dp {
dp[i] = make([]int, n+1)
for j := range dp[i] {
dp[i][j] = -1
}
}
return process2(cost, time, 0, n, dp)
} // process2 represents the recursive function in the second approach of the Java code.
func process2(cost []int, time []int, i int, s int, dp [][]int) int {
if s <= 0 {
return 0
}
if dp[i][s] != -1 {
return dp[i][s]
}
var ans int
if i == len(cost) {
ans = math.MaxInt32
} else {
p1 := process2(cost, time, i+1, s, dp)
p2 := math.MaxInt32
next2 := process2(cost, time, i+1, s-1-time[i], dp)
if next2 != math.MaxInt32 {
p2 = cost[i] + next2
}
ans = int(math.Min(float64(p1), float64(p2)))
}
dp[i][s] = ans
return ans
} // paintWalls3 is the third function from the given Java code.
func paintWalls3(cost []int, time []int) int {
n := len(cost)
dp := make([]int, n+1)
for i := range dp {
dp[i] = math.MaxInt32
}
dp[0] = 0
for i := n - 1; i >= 0; i-- {
for s := n; s >= 1; s-- {
if s-1-time[i] <= 0 {
dp[s] = int(math.Min(float64(dp[s]), float64(cost[i])))
} else if dp[s-1-time[i]] != math.MaxInt32 {
dp[s] = int(math.Min(float64(dp[s]), float64(cost[i]+dp[s-1-time[i]])))
}
}
}
return dp[n]
} func main() {
cost := []int{1, 2, 3, 2}
time := []int{1, 2, 3, 2}
fmt.Println("Result 1:", paintWalls1(cost, time))
fmt.Println("Result 2:", paintWalls2(cost, time))
fmt.Println("Result 3:", paintWalls3(cost, time))
}

rust完整代码如下:

fn paint_walls1(cost: Vec<i32>, time: Vec<i32>) -> i32 {
process1(&cost, &time, 0, cost.len() as i32)
} fn process1(cost: &Vec<i32>, time: &Vec<i32>, i: i32, s: i32) -> i32 {
if s <= 0 {
return 0;
}
if (i as usize) == cost.len() {
return i32::MAX;
} else {
let p1 = process1(cost, time, i + 1, s);
let mut p2 = i32::MAX;
let next2 = process1(cost, time, i + 1, s - 1 - time[i as usize]);
if next2 != i32::MAX {
p2 = cost[i as usize] + next2;
}
return p1.min(p2);
}
} fn paint_walls2(cost: Vec<i32>, time: Vec<i32>) -> i32 {
let n = cost.len();
let mut dp = vec![vec![-1; n + 1]; n + 1];
process2(&cost, &time, 0, n as i32, &mut dp)
} fn process2(cost: &Vec<i32>, time: &Vec<i32>, i: i32, s: i32, dp: &mut Vec<Vec<i32>>) -> i32 {
if s <= 0 {
return 0;
}
if dp[i as usize][s as usize] != -1 {
return dp[i as usize][s as usize];
}
let ans;
if (i as usize) == cost.len() {
ans = i32::MAX;
} else {
let p1 = process2(cost, time, i + 1, s, dp);
let mut p2 = i32::MAX;
let next2 = process2(cost, time, i + 1, s - 1 - time[i as usize], dp);
if next2 != i32::MAX {
p2 = cost[i as usize] + next2;
}
ans = p1.min(p2);
}
dp[i as usize][s as usize] = ans;
ans
} fn paint_walls3(cost: Vec<i32>, time: Vec<i32>) -> i32 {
let n = cost.len();
let mut dp = vec![i32::MAX; n + 1];
dp[0] = 0;
for i in (0..n).rev() {
for s in (1..=n as i32).rev() {
if s - 1 - time[i] <= 0 {
dp[s as usize] = dp[s as usize].min(cost[i]);
} else if dp[(s - 1 - time[i]) as usize] != i32::MAX {
dp[s as usize] = dp[s as usize].min(cost[i] + dp[(s - 1 - time[i]) as usize]);
}
}
}
dp[n]
} fn main() {
let cost = vec![1, 2, 3, 2];
let time = vec![1, 2, 3, 2]; let result1 = paint_walls1(cost.clone(), time.clone());
let result2 = paint_walls2(cost.clone(), time.clone());
let result3 = paint_walls3(cost.clone(), time.clone()); println!("Result for paint_walls1: {}", result1);
println!("Result for paint_walls2: {}", result2);
println!("Result for paint_walls3: {}", result3);
}

c++完整代码如下:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std; // 暴力递归
int process1(vector<int>& cost, vector<int>& time, int i, int s) {
if (s <= 0) {
return 0;
}
if (i == cost.size()) {
return INT_MAX;
}
else {
int p1 = process1(cost, time, i + 1, s);
int p2 = INT_MAX;
int next2 = process1(cost, time, i + 1, s - 1 - time[i]);
if (next2 != INT_MAX) {
p2 = cost[i] + next2;
}
return min(p1, p2);
}
} int paintWalls1(vector<int>& cost, vector<int>& time) {
return process1(cost, time, 0, cost.size());
} // 暴力递归改记忆化搜索
int process2(vector<int>& cost, vector<int>& time, int i, int s, vector<vector<int>>& dp) {
if (s <= 0) {
return 0;
}
if (dp[i][s] != -1) {
return dp[i][s];
}
int ans;
if (i == cost.size()) {
ans = INT_MAX;
}
else {
int p1 = process2(cost, time, i + 1, s, dp);
int p2 = INT_MAX;
int next2 = process2(cost, time, i + 1, s - 1 - time[i], dp);
if (next2 != INT_MAX) {
p2 = cost[i] + next2;
}
ans = min(p1, p2);
}
dp[i][s] = ans;
return ans;
} int paintWalls2(vector<int>& cost, vector<int>& time) {
int n = cost.size();
vector<vector<int>> dp(n + 1, vector<int>(n + 1, -1));
return process2(cost, time, 0, n, dp);
} // 严格位置依赖的动态规划 + 空间压缩
int paintWalls3(vector<int>& cost, vector<int>& time) {
int n = cost.size();
vector<int> dp(n + 1, INT_MAX);
dp[0] = 0;
for (int i = n - 1; i >= 0; i--) {
for (int s = n; s >= 1; s--) {
if (s - 1 - time[i] <= 0) {
dp[s] = min(dp[s], cost[i]);
}
else if (dp[s - 1 - time[i]] != INT_MAX) {
dp[s] = min(dp[s], cost[i] + dp[s - 1 - time[i]]);
}
}
}
return dp[n];
} int main() {
vector<int> cost = { 1, 2, 3, 2 };
vector<int> time = { 1, 2, 3, 2 }; cout << "Result for paintWalls1: " << paintWalls1(cost, time) << endl;
cout << "Result for paintWalls2: " << paintWalls2(cost, time) << endl;
cout << "Result for paintWalls3: " << paintWalls3(cost, time) << endl; return 0;
}

c语言完整代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h> int process1(int* cost, int* time, int i, int s, int costSize); int paintWalls1(int* cost, int costSize, int* time, int timeSize) {
return process1(cost, time, 0, costSize, costSize);
} int process1(int* cost, int* time, int i, int s, int costSize) {
if (s <= 0) {
return 0;
}
if (i == costSize) {
return INT_MAX;
}
else {
int p1 = process1(cost, time, i + 1, s, costSize);
int p2 = INT_MAX;
int next2 = process1(cost, time, i + 1, s - 1 - time[i], costSize);
if (next2 != INT_MAX) {
p2 = cost[i] + next2;
}
return (p1 < p2) ? p1 : p2;
}
} int process2(int* cost, int* time, int i, int s, int costSize, int** dp); int paintWalls2(int* cost, int costSize, int* time, int timeSize) {
int** dp = (int**)malloc((costSize + 1) * sizeof(int*));
for (int i = 0; i <= costSize; i++) {
dp[i] = (int*)malloc((costSize + 1) * sizeof(int));
for (int j = 0; j <= costSize; j++) {
dp[i][j] = -1;
}
}
int result = process2(cost, time, 0, costSize, costSize, dp);
for (int i = 0; i <= costSize; i++) {
free(dp[i]);
}
free(dp);
return result;
} int process2(int* cost, int* time, int i, int s, int costSize, int** dp) {
if (s <= 0) {
return 0;
}
if (dp[i][s] != -1) {
return dp[i][s];
}
int ans;
if (i == costSize) {
ans = INT_MAX;
}
else {
int p1 = process2(cost, time, i + 1, s, costSize, dp);
int p2 = INT_MAX;
int next2 = process2(cost, time, i + 1, s - 1 - time[i], costSize, dp);
if (next2 != INT_MAX) {
p2 = cost[i] + next2;
}
ans = (p1 < p2) ? p1 : p2;
}
dp[i][s] = ans;
return ans;
} int paintWalls3(int* cost, int costSize, int* time, int timeSize); int paintWalls3(int* cost, int costSize, int* time, int timeSize) {
int* dp = (int*)malloc((costSize + 1) * sizeof(int));
for (int i = 0; i <= costSize; i++) {
dp[i] = INT_MAX;
}
dp[0] = 0;
for (int i = costSize - 1; i >= 0; i--) {
for (int s = costSize; s >= 1; s--) {
if (s - 1 - time[i] <= 0) {
dp[s] = (dp[s] < cost[i]) ? dp[s] : cost[i];
}
else if (dp[s - 1 - time[i]] != INT_MAX) {
dp[s] = (dp[s] < cost[i] + dp[s - 1 - time[i]]) ? dp[s] : cost[i] + dp[s - 1 - time[i]];
}
}
}
int result = dp[costSize];
free(dp);
return result;
} int main() {
int cost[] = { 1, 2, 3, 2 };
int time[] = { 1, 2, 3, 2 }; int result1 = paintWalls1(cost, 4, time, 4);
printf("Result of paintWalls1: %d\n", result1); int result2 = paintWalls2(cost, 4, time, 4);
printf("Result of paintWalls2: %d\n", result2); int result3 = paintWalls3(cost, 4, time, 4);
printf("Result of paintWalls3: %d\n", result3);
return 0;
}

2024-01-03:用go语言,给你两个长度为 n 下标从 0 开始的整数数组 cost 和 time, 分别表示给 n 堵不同的墙刷油漆需要的开销和时间。你有两名油漆匠, 一位需要 付费 的油漆匠的更多相关文章

  1. JS 格式化时间(获取两个日期之间的每一天、每一月、每半小时、每一秒)

    时间戳转换为时间 // 时间戳转换为时间 function timestampToTime(timestamp, isMs = true) { const date = new Date(timest ...

  2. Tensorflow学习笔记2019.01.03

    tensorflow学习笔记: 3.2 Tensorflow中定义数据流图 张量知识矩阵的一个超集. 超集:如果一个集合S2中的每一个元素都在集合S1中,且集合S1中可能包含S2中没有的元素,则集合S ...

  3. JAVA 时间差距,两个时间相差多少天,时,分,秒

    JAVA 时间差距,两个时间相差多少天,时,分,秒 package io; import java.text.DateFormat; import java.text.ParseException; ...

  4. SQL获取当前时间月份为两位数

    --获取当前时间月份为两位数 )),) --获取当前时间上月月份为两位数 , )),)

  5. git rev-list 按照时间来列出两个 commit id 之间的相差数

    git rev-list 按照时间来列出两个 commit id 之间的相差数 git rev-list: Lists commit objects in reverse chronological ...

  6. AE工程渲染的时间缓慢,两种方法减少对AE工程渲染的时间!

    AE工程渲染的时间缓慢,两种方法减少对AE工程渲染的时间!3秒的片头,渲染时间竟然要花1个多小时,很多新手都产生过这样的疑问?是哪里不对吗?如何才能减少渲染视频的时间?且听我一一道来.主要原因是:工程 ...

  7. c语言经典算法——查找一个整数数组中第二大数

    题目: 实现一个函数,查找一个整数数组中第二大数. 算法思想: 设置两个变量max1和max2,用来保存最大数和第二大数,然后将数组剩余的数依次与这两个数比较,如果这个数a比max1大,则先将max1 ...

  8. 实现两个N*N矩阵的乘法,矩阵由一维数组表示

    实现两个N*N矩阵的乘法,矩阵由一维数组表示. 先介绍一下矩阵的加法: void Add(int rows, int cols) { ;i<rows;i++) { ;j<cols;j++) ...

  9. C语言中宏定义(#define)时do{}while(0)的价值(转)

    C语言中宏定义(#define)时do{}while(0)的价值 最近在新公司的代码中发现到处用到do{...}while(0),google了一下,发现Stack Overflow上早有很多讨论,总 ...

  10. C# 语言规范_版本5.0 (第12章 数组)

    1. 数组 数组是一种包含若干变量的数据结构,这些变量都可以通过计算索引进行访问.数组中包含的变量(又称数组的元素)具有相同的类型,该类型称为数组的元素类型. 数组有一个“秩”,它确定和每个数组元素关 ...

随机推荐

  1. 「ABC 218」解集

    E 倒流一下,然后把负权边置零后跑 MST 即可. #include<cstdio> #include<vector> #include<algorithm> us ...

  2. Solution -「洛谷 P2000」拯救世界

    Description Link. 概括什么好麻烦哦 w. Solution 生成函数裸题. 把所有情况罗列出来: kkk: 金: \(1+x^6+x^{12}+\dots=\frac{1}{1-x^ ...

  3. FreeSWITCH容器化问题之rtp端口占用

    操作系统 :CentOS 7.6_x64.debian 11 (bullseye,docker) FreeSWITCH版本 :1.10.9 Docker版本:23.0.6 FreeSWITCH容器化带 ...

  4. 理解并掌握C#的Channel:从使用案例到源码解读(一)

    引言 在C#的并发编程中,Channel是一种非常强大的数据结构,用于在生产者和消费者之间进行通信.本文将首先通过一个实际的使用案例,介绍如何在C#中使用Channel,然后深入到Channel的源码 ...

  5. 异常:no transaction is in progress

    转载请注明出处: 在使用  @Scheduled 注解创建了一个定时任务,并通过定时任务不断向mysql写入数据,写入数据的方式是通过 jpa 的方式,在代码运行的过程中出现错误:no transac ...

  6. c语言代码练习14

    //设计一个猜数字游戏,需要提示猜大了还是小了,直到猜对为止 #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include & ...

  7. python第2~5章 学习笔记

    # 第2~5章 学习笔记 ## 什么是计算机语言 计算机就是一台用来计算机的机器,人让计算机干什么计算机就得干什么! 需要通过计算机的语言来控制计算机(编程语言)! 计算机语言其实和人类的语言没有本质 ...

  8. it 作形式主语:It's no good doing sth.

    It's no good doing sth. 这个 句型其实是一个省 略介词 in 的句型,完整形式是 It's no good in doing sth. 其中, good 是形容词,和介词 in ...

  9. MySQL误删恢复方法1

    MySQL不同于oracle,没有闪回查询这类概念,但网上流传几个闪回的开源工具如 binglog2sql.MyFlash,可以使用binglog日志进行误操作数据的恢复. 笔者以前测试过 bingl ...

  10. Python join拼接

    import os print(os.path.join("I","love","you.")) # /XXX 代表的是绝对路径 这个变量之 ...