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. 数组 数组是一种包含若干变量的数据结构,这些变量都可以通过计算索引进行访问.数组中包含的变量(又称数组的元素)具有相同的类型,该类型称为数组的元素类型. 数组有一个“秩”,它确定和每个数组元素关 ...
随机推荐
- ESS、RSS、TSS
回归平方和 ESS,残差平方和 RSS,总体平方和 TSS 残差平方和越小,自变量与因变量之间的相关性越好 总变差(TSS):被解释变量Y的观测值与其平均值的离差平方和(总平方和)(说明 Y 的总变动 ...
- TOP GP 把已经编译的per反编回对应版本的4fd(画面档)
由于GP5.1,5.2,5.3的genero对应版本画面档开发互不兼容,下面提供各版本之间互转的操作方法: xshell切换到要反编译的per档目录,执行以下命令,就会在同目录下生成对应4fd档资料 ...
- 重温dp——最长上升公共子序列
一道经典的dp了 题目描述 给出 1,2,-,n 的两个排列 P1 和 P2 ,求它们的最长公共子序列. 输入格式 第一行是一个数 n. 接下来两行,每行为 n 个数,为自然数 1,2,-,n 的一 ...
- C#软件架构设计原则
软件架构设计原则 学习设计原则是学习设计模式的基础.在实际的开发过程中,并不是一定要求所有的代码都遵循设计原则,而是要综合考虑人力.成本.时间.质量,不刻意追求完美,要在适当的场景遵循设计原则.这体现 ...
- 虹科干货| 虹科Redis企业版数据库:告别游戏卡顿,让快乐加速!
"卡顿一分钟,玩家两行泪" 游戏已成为年轻人最主要的消遣娱乐方式之一,游戏卡顿给玩家带来糟糕游戏体验背后的原因是什么?数据存储与查询速度不够快! 游戏开发领域,不仅拥有海量的数 ...
- GameFramework摘录 - 3. 使用interface定义对外接口
GameFramework的模块密封性相当好,如果使用unity的assemblydef,其设计可以把框架项目与自己的游戏逻辑分离开来. 除一些常用的基类.枚举等,核心模块设置为internal权限, ...
- 搞懂闭包JavaScript的GC机制
其实不管什么语言,都有一套垃圾回收机制.为什么要有垃圾回收机制?因为内存,程序运行需要内存,如果没有垃圾回收(循环引用,内存泄漏),那么内存占用就会越来越高,轻点说会影响性能卡顿,严重的直接导致崩溃. ...
- 持续进化,快速转录,Faster-Whisper对视频进行双语字幕转录实践(Python3.10)
Faster-Whisper是Whisper开源后的第三方进化版本,它对原始的 Whisper 模型结构进行了改进和优化.这包括减少模型的层数.减少参数量.简化模型结构等,从而减少了计算量和内存消耗, ...
- go 中如何实现定时任务
定时任务简介 定时任务是指按照预定的时间间隔或特定时间点自动执行的计划任务或操作.这些任务通常用于自动化重复性的工作,以减轻人工操作的负担,提高效率.在计算机编程和应用程序开发中,定时任务是一种常见的 ...
- 使用rancher rke快速安装k8s集群
概述 Rancher Kubernetes Engine(RKE)是一个用于部署.管理和运行Kubernetes集群的开源工具.旨在简化Kubernetes集群的部署和操作. RKE具有以下特点和功能 ...