2024-01-03:用go语言,给你两个长度为 n 下标从 0 开始的整数数组 cost 和 time, 分别表示给 n 堵不同的墙刷油漆需要的开销和时间。你有两名油漆匠, 一位需要 付费 的油漆匠
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:
来自左程云。
大体过程如下:
paintWalls1 函数
1.paintWalls1 函数是基于递归方法的解决方案。
2.在 process1 函数中,通过递归方式将每种情况下的最小开销计算出来。
3.递归调用时考虑两种情况,选择当前墙刷或者不刷,计算出最小开销。
4.该方法在递归调用的过程中可能会有很多重复计算,效率可能不高。
paintWalls2 函数
1.paintWalls2 函数采用了记忆化搜索的方式。
2.定义了一个二维数组 dp 用于记录已经计算过的结果,避免重复计算。
3.通过递归+记忆化搜索的方式优化了重复计算,提高了效率。
paintWalls3 函数
1.paintWalls3 函数采用了动态规划的方式。
2.使用一个一维数组 dp 保存不同墙数下的最小开销。
3.结合循环和动态递推的方式,迭代计算每墙的最小开销,直到第 n 墙。
时间和空间复杂度
时间复杂度:
paintWalls1使用了递归,可能有大量重复计算,其时间复杂度为 O(2^n)。paintWalls2和paintWalls3使用了记忆化搜索和动态规划,时间复杂度都为 O(n^2),其中 n 为墙的数量。
空间复杂度:
paintWalls1和paintWalls2的额外空间复杂度为 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 堵不同的墙刷油漆需要的开销和时间。你有两名油漆匠, 一位需要 付费 的油漆匠的更多相关文章
- JS 格式化时间(获取两个日期之间的每一天、每一月、每半小时、每一秒)
时间戳转换为时间 // 时间戳转换为时间 function timestampToTime(timestamp, isMs = true) { const date = new Date(timest ...
- Tensorflow学习笔记2019.01.03
tensorflow学习笔记: 3.2 Tensorflow中定义数据流图 张量知识矩阵的一个超集. 超集:如果一个集合S2中的每一个元素都在集合S1中,且集合S1中可能包含S2中没有的元素,则集合S ...
- JAVA 时间差距,两个时间相差多少天,时,分,秒
JAVA 时间差距,两个时间相差多少天,时,分,秒 package io; import java.text.DateFormat; import java.text.ParseException; ...
- SQL获取当前时间月份为两位数
--获取当前时间月份为两位数 )),) --获取当前时间上月月份为两位数 , )),)
- git rev-list 按照时间来列出两个 commit id 之间的相差数
git rev-list 按照时间来列出两个 commit id 之间的相差数 git rev-list: Lists commit objects in reverse chronological ...
- AE工程渲染的时间缓慢,两种方法减少对AE工程渲染的时间!
AE工程渲染的时间缓慢,两种方法减少对AE工程渲染的时间!3秒的片头,渲染时间竟然要花1个多小时,很多新手都产生过这样的疑问?是哪里不对吗?如何才能减少渲染视频的时间?且听我一一道来.主要原因是:工程 ...
- c语言经典算法——查找一个整数数组中第二大数
题目: 实现一个函数,查找一个整数数组中第二大数. 算法思想: 设置两个变量max1和max2,用来保存最大数和第二大数,然后将数组剩余的数依次与这两个数比较,如果这个数a比max1大,则先将max1 ...
- 实现两个N*N矩阵的乘法,矩阵由一维数组表示
实现两个N*N矩阵的乘法,矩阵由一维数组表示. 先介绍一下矩阵的加法: void Add(int rows, int cols) { ;i<rows;i++) { ;j<cols;j++) ...
- C语言中宏定义(#define)时do{}while(0)的价值(转)
C语言中宏定义(#define)时do{}while(0)的价值 最近在新公司的代码中发现到处用到do{...}while(0),google了一下,发现Stack Overflow上早有很多讨论,总 ...
- C# 语言规范_版本5.0 (第12章 数组)
1. 数组 数组是一种包含若干变量的数据结构,这些变量都可以通过计算索引进行访问.数组中包含的变量(又称数组的元素)具有相同的类型,该类型称为数组的元素类型. 数组有一个“秩”,它确定和每个数组元素关 ...
随机推荐
- 「ABC 218」解集
E 倒流一下,然后把负权边置零后跑 MST 即可. #include<cstdio> #include<vector> #include<algorithm> us ...
- Solution -「洛谷 P2000」拯救世界
Description Link. 概括什么好麻烦哦 w. Solution 生成函数裸题. 把所有情况罗列出来: kkk: 金: \(1+x^6+x^{12}+\dots=\frac{1}{1-x^ ...
- FreeSWITCH容器化问题之rtp端口占用
操作系统 :CentOS 7.6_x64.debian 11 (bullseye,docker) FreeSWITCH版本 :1.10.9 Docker版本:23.0.6 FreeSWITCH容器化带 ...
- 理解并掌握C#的Channel:从使用案例到源码解读(一)
引言 在C#的并发编程中,Channel是一种非常强大的数据结构,用于在生产者和消费者之间进行通信.本文将首先通过一个实际的使用案例,介绍如何在C#中使用Channel,然后深入到Channel的源码 ...
- 异常:no transaction is in progress
转载请注明出处: 在使用 @Scheduled 注解创建了一个定时任务,并通过定时任务不断向mysql写入数据,写入数据的方式是通过 jpa 的方式,在代码运行的过程中出现错误:no transac ...
- c语言代码练习14
//设计一个猜数字游戏,需要提示猜大了还是小了,直到猜对为止 #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include & ...
- python第2~5章 学习笔记
# 第2~5章 学习笔记 ## 什么是计算机语言 计算机就是一台用来计算机的机器,人让计算机干什么计算机就得干什么! 需要通过计算机的语言来控制计算机(编程语言)! 计算机语言其实和人类的语言没有本质 ...
- it 作形式主语:It's no good doing sth.
It's no good doing sth. 这个 句型其实是一个省 略介词 in 的句型,完整形式是 It's no good in doing sth. 其中, good 是形容词,和介词 in ...
- MySQL误删恢复方法1
MySQL不同于oracle,没有闪回查询这类概念,但网上流传几个闪回的开源工具如 binglog2sql.MyFlash,可以使用binglog日志进行误操作数据的恢复. 笔者以前测试过 bingl ...
- Python join拼接
import os print(os.path.join("I","love","you.")) # /XXX 代表的是绝对路径 这个变量之 ...