首页 > 其他分享 >2023-05-06:X轴上有一些机器人和工厂。给你一个整数数组robot,其中robot[i]是第i个机器人的位置 再给你一个二维整数数组factory,其中 factory[j] = [posit

2023-05-06:X轴上有一些机器人和工厂。给你一个整数数组robot,其中robot[i]是第i个机器人的位置 再给你一个二维整数数组factory,其中 factory[j] = [posit

时间:2023-05-06 23:23:33浏览次数:49  
标签:deque int 机器人 factory robot dp

2023-05-06:X轴上有一些机器人和工厂。给你一个整数数组robot,其中robot[i]是第i个机器人的位置

再给你一个二维整数数组factory,其中 factory[j] = [positionj, limitj]

表示第 j 个工厂的位置在 positionj ,且第 j 个工厂最多可以修理 limitj 个机器人

每个机器人所在的位置 互不相同。每个工厂所在的位置也互不相同

注意一个机器人可能一开始跟一个工厂在相同的位置

所有机器人一开始都是坏的,他们会沿着设定的方向一直移动

设定的方向要么是 X 轴的正方向,要么是 X 轴的负方向

当一个机器人经过一个没达到上限的工厂时,这个工厂会维修这个机器人,且机器人停止移动

任何时刻,你都可以设置 部分 机器人的移动方向

你的目标是最小化所有机器人总的移动距离

请你返回所有机器人移动的最小总距离

注意:

所有机器人移动速度相同

如果两个机器人移动方向相同,它们永远不会碰撞

如果两个机器人迎面相遇,它们也不会碰撞,它们彼此之间会擦肩而过

如果一个机器人经过了一个已经达到上限的工厂,机器人会当作工厂不存在,继续移动

机器人从位置 x 到位置 y 的移动距离为 |y - x|

1 <= robot.length, factory.length <= 100

factory[j].length == 2

-10 ^ 9 <= robot[i], positionj <= 10 ^ 9

0 <= limitj <= robot.length

测试数据保证所有机器人都可以被维修。

输入:robot = [0,4,6], factory = [[2,2],[6,2]]。

输出:4。

答案2023-05-06:

算法1:

1.首先对机器人位置数组 robot 进行排序,按照从小到大的顺序排列。

2.对工厂位置数组 factory 按照第一个元素排序,也就是按照工厂所在的位置从小到大排列。

3.创建一个二维数组 dp,大小为 (n, m),其中 $n$ 是机器人个数,$m$ 是工厂个数。初始时,所有元素置为 -1。

4.调用递归函数 process1(robot, factory, n-1, m-1, dp) 计算最小总距离。

--1.如果机器人已经全部处理完毕(即 i < 0),返回 0。

--2.如果已经没有可用的工厂(即 j < 0),返回最大整数值(表示当前状态不合法,无解)。

--3.如果 dp[i][j] 已经计算过了,直接返回这个值。

--4 定义变量 ans 表示当前状态下的最小距离,初始化为左边一个工厂的最小距离。然后遍历当前工厂能够维修的机器人,计算这些机器人到当前工厂的距离,并且调用递归函数 process1 计算剩余机器人和工厂的最小距离。

--5.在所有可能的状态中选择一个距离最小的状态,并返回这个距离。

5.返回递归函数 process1 的计算结果。

时间复杂度:O((n ^ m)m),其中 n 是机器人个数,m 是工厂个数。

空间复杂度:O(nm)。

算法2:

1.首先对机器人位置数组 robot 进行排序,按照从小到大的顺序排列。

2.对工厂位置数组 factory 按照第一个元素排序,也就是按照工厂所在的位置从小到大排列。

3.创建一个二维数组 dp,大小为 (n, m),其中 $n$ 是机器人个数,$m$ 是工厂个数。初始时,所有元素置为最大整数值。

4.遍历机器人和工厂,使用动态规划计算最小总距离。

--1.定义变量 ans 表示当前状态下的最小距离,初始化为左边一个工厂的最小距离。

--2.定义变量 distance 表示当前机器人到当前工厂的距离,初始化为 0。

--3.遍历当前工厂能够维修的机器人,计算这些机器人到当前工厂的距离,并且查找剩余机器人和工厂的最小距离。

--4.更新变量 ansdistance

--5.在所有可能的状态中选择一个距离最小的状态,并将这个距离赋值给当前状态。

5.返回 dp[n-1][m-1],即机器人全部处理完毕时到达最后一个工厂所需要的最小总距离。

算法2时间复杂度:O(n(m ^ 2)),其中 n 是机器人个数,m 是工厂个数。

空间复杂度:O(nm)。

算法3:

1.首先对机器人位置数组 robot 进行排序,按照从小到大的顺序排列。

2.对工厂位置数组 factory 按照第一个元素排序,也就是按照工厂所在的位置从小到大排列。

3.创建一个二维数组 dp,大小为 (n, m),其中 $n$ 是机器人个数,$m$ 是工厂个数。初始时,所有元素置为最大整数值。

4.创建一个双端队列 deque,用于维护每个工厂能够维修的机器人的最小距离。

5.遍历工厂,对于每个工厂,使用动态规划计算最小总距离。

--1.定义变量 add 表示当前机器人到当前工厂之前的距离和,初始化为 0。

--2.定义变量 limit 表示当前工厂能够维修的机器人数量限制。

--3.初始化双端队列 deque,将 (i, 0) 加入队列。其中 $i$ 表示机器人的下标,0 表示到达当前工厂之前的距离和为 0。

--4.遍历机器人,计算当前状态下的最小距离。

----1.如果左边有一个工厂,选择它作为当前状态的备选值。

----2.从队列中取出所有与当前机器人距离小于等于 limit 的机器人,并计算这些机器人到当前工厂的距离和。如果队列为空,则跳过该步骤。

----3.在所有可能的状态中选择一个距离最小的状态,并将这个距离赋值给当前状态。

----4.将当前机器人加入队列,更新队列中的元素。

--5.返回 dp[n-1][m-1],即机器人全部处理完毕时到达最后一个工厂所需要的最小总距离。

6.返回 dp[n-1][m-1],即机器人全部处理完毕时到达最后一个工厂所需要的最小总距离。

时间复杂度:O(nm log n),其中 n 是机器人个数,m 是工厂个数。

空间复杂度:O(nm)。

go三种算法完整代码如下:

package main

import (
	"fmt"
	"math"
	"sort"
)

func minimumTotalDistance1(robot []int, factory [][]int) int64 {
	n := len(robot)
	m := len(factory)
	sort.Ints(robot)
	sortFactoryByFirst(factory)
	dp := make([][]int64, n)
	for i := range dp {
		dp[i] = make([]int64, m)
		for j := range dp[i] {
			dp[i][j] = -1
		}
	}
	return process1(robot, factory, n-1, m-1, dp)
}

func process1(robot []int, factory [][]int, i, j int, dp [][]int64) int64 {
	if i < 0 {
		return 0
	}
	if j < 0 {
		return math.MaxInt64
	}
	if dp[i][j] != -1 {
		return dp[i][j]
	}
	ans := process1(robot, factory, i, j-1, dp)
	distance := int64(0)
	for l, num := i, 1; l >= 0 && num <= factory[j][1]; l, num = l-1, num+1 {
		curAns := process1(robot, factory, l-1, j-1, dp)
		d := int64(abs(robot[l] - factory[j][0]))
		distance += d
		if curAns != math.MaxInt64 {
			ans = min(ans, curAns+distance)
		}
	}
	dp[i][j] = ans
	return ans
}

func sortFactoryByFirst(a [][]int) {
	sort.Slice(a, func(i, j int) bool {
		return a[i][0] < a[j][0]
	})
}

func abs(x int) int {
	if x < 0 {
		return -x
	}
	return x
}

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

func minimumTotalDistance2(robot []int, factory [][]int) int64 {
	n := len(robot)
	m := len(factory)
	sort.Ints(robot)
	sortFactoryByFirst(factory)
	dp := make([][]int64, n)
	for i := 0; i < n; i++ {
		dp[i] = make([]int64, m)
		for j := 0; j < m; j++ {
			ans := int64(math.MaxInt64)
			if j > 0 {
				ans = dp[i][j-1]
			}
			distance := int64(0)
			for l, num := i, 1; l >= 0 && num <= factory[j][1]; l, num = l-1, num+1 {
				curAns := int64(0)
				if l-1 < 0 {
					curAns = 0
				} else if j-1 < 0 {
					curAns = math.MaxInt64
				} else {
					curAns = dp[l-1][j-1]
				}
				distance += int64(abs(robot[l] - factory[j][0]))
				if curAns != math.MaxInt64 {
					ans = min(ans, curAns+distance)
				}
			}
			dp[i][j] = ans
		}
	}
	return dp[n-1][m-1]
}

func minimumTotalDistance3(robot []int, factory [][]int) int64 {
	n := len(robot)
	m := len(factory)
	sort.Ints(robot)
	sortFactoryByFirst(factory)
	dp := make([][]int64, n)
	for i := 0; i < n; i++ {
		dp[i] = make([]int64, m)
		for j := 0; j < m; j++ {
			dp[i][j] = math.MaxInt64
		}
	}
	deque := make([][]int64, n+1)
	for i := 0; i < n+1; i++ {
		deque[i] = make([]int64, 2)
	}
	var l, r int
	for j := 0; j < m; j++ {
		add := int64(0)
		limit := int64(factory[j][1])
		l = 0
		r = 1
		deque[l][0] = -1
		deque[l][1] = 0
		for i := 0; i < n; i++ {
			p1 := int64(math.MaxInt64)
			if j > 0 {
				p1 = dp[i][j-1]
			}
			add += int64(abs(robot[i] - factory[j][0]))
			if deque[l][0] == int64(i)-limit-1 {
				l++
			}
			p2 := int64(math.MaxInt64)
			if l < r {
				best := deque[l][1]
				if best != math.MaxInt64 {
					p2 = add + best
				}
			}
			dp[i][j] = min(p1, p2)
			fill := p1
			if p1 == math.MaxInt64 {
				fill = p1
			} else {
				fill = p1 - add
			}
			for l < r && deque[r-1][1] >= fill {
				r--
			}
			deque[r][0] = int64(i)
			deque[r][1] = fill
			r++
		}
	}
	return dp[n-1][m-1]
}

func main() {
	if true {
		robot := []int{0, 4, 6}
		factory := [][]int{{2, 2}, {6, 2}}
		fmt.Println(minimumTotalDistance1(robot, factory))
	}
	if true {
		robot := []int{0, 4, 6}
		factory := [][]int{{2, 2}, {6, 2}}
		fmt.Println(minimumTotalDistance2(robot, factory))
	}

	if true {
		robot := []int{0, 4, 6}
		factory := [][]int{{2, 2}, {6, 2}}
		fmt.Println(minimumTotalDistance3(robot, factory))
	}
}

在这里插入图片描述

rust第2种和第3种算法代码如下:

fn minimum_total_distance2(robot: Vec<i32>, factory: Vec<Vec<i32>>) -> i64 {
    let n = robot.len();
    let m = factory.len();

    // 排序操作
    let mut sorted_robot = robot.clone();
    sorted_robot.sort_unstable();

    let mut sorted_factory = factory.clone();
    sorted_factory.sort_unstable_by_key(|a| a[0]);

    let mut dp = vec![vec![std::i64::MAX; m]; n];

    for i in 0..n {
        for j in 0..m {
            // ans = dp[i][j - 1] -> 0...i -> 0...j-1
            let mut ans = std::i64::MAX;
            if j >= 1 {
                ans = dp[i][j - 1];
            }
            let mut distance = 0;
            for (l, num) in (0..=i).rev().zip(1..=factory[j][1]) {
                let cur_ans = if l == 0 {
                    0
                } else if j == 0 {
                    std::i64::MAX
                } else {
                    dp[l - 1][j - 1]
                };
                let d = (robot[l] - factory[j][0]).abs() as i64;
                distance += d;
                if cur_ans != std::i64::MAX {
                    ans = ans.min(cur_ans + distance);
                }
            }
            dp[i][j] = ans;
        }
    }

    dp[n - 1][m - 1]
}

fn minimum_total_distance3(robot: Vec<i32>, factory: Vec<Vec<i32>>) -> i64 {
    let n = robot.len();
    let m = factory.len();

    // 排序操作
    let mut sorted_robot = robot.clone();
    sorted_robot.sort_unstable();

    let mut sorted_factory = factory.clone();
    sorted_factory.sort_unstable_by_key(|a| a[0]);

    let mut dp = vec![vec![std::i64::MAX; m]; n];

    for j in 0..m {
        let mut add = 0;
        let limit = factory[j][1] as usize;
        let mut l = 0;
        let mut r = 1;
        let mut deque = vec![vec![0; 2]; n + 1];
        deque[l][0] = std::i64::MAX;
        deque[l][1] = 0;
        for i in 0..n {
            let p1 = if j >= 1 { dp[i][j - 1] } else { std::i64::MAX };
            add += (sorted_robot[i] - sorted_factory[j][0]).abs() as i64;
            while l < r && deque[l][0] == i as i64 - limit as i64 - 1 {
                l += 1;
            }
            let p2 = if l < r && deque[l][1] != std::i64::MAX {
                add + deque[l][1]
            } else {
                std::i64::MAX
            };
            dp[i][j] = p1.min(p2);
            let fill = if p1 == std::i64::MAX { p1 } else { p1 - add };
            while l < r && deque[r - 1][1] >= fill {
                r -= 1;
            }
            deque[r][0] = i as i64;
            deque[r][1] = fill;
            r += 1;
        }
    }

    dp[n - 1][m - 1]
}

fn main() {
    let robot = vec![0, 4, 6];
    let factory = vec![vec![2, 2], vec![6, 2]];
    println!(
        "{}",
        minimum_total_distance2(robot.clone(), factory.clone())
    );
    println!(
        "{}",
        minimum_total_distance3(robot.clone(), factory.clone())
    );
}

在这里插入图片描述

c++三种算法完整代码如下:

#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>

using namespace std;

struct Pair {
    int x, y;
};

void sortFactoryByFirst(vector<vector<int>>& factory) {
    sort(factory.begin(), factory.end(), [](const auto& a, const auto& b) {
        return a[0] < b[0];
        });
}

int64_t minimumTotalDistance1(vector<int>& robot, vector<vector<int>>& factory, int n, int m, vector<vector<int64_t>>& dp) {
    if (n < 0) {
        return 0;
    }
    if (m < 0) {
        return INT64_MAX;
    }
    if (dp[n][m] != -1) {
        return dp[n][m];
    }
    int64_t ans = minimumTotalDistance1(robot, factory, n, m - 1, dp);
    int64_t distance = 0;
    for (int l = n, num = 1; l >= 0 && num <= factory[m][1]; l--, num++) {
        int64_t curAns = minimumTotalDistance1(robot, factory, l - 1, m - 1, dp);
        int64_t d = abs(robot[l] - factory[m][0]);
        distance += d;
        if (curAns != INT64_MAX) {
            ans = min(ans, curAns + distance);
        }
    }
    dp[n][m] = ans;
    return ans;
}

int64_t minimumTotalDistance2(vector<int>& robot, vector<vector<int>>& factory, int n, int m) {
    sort(robot.begin(), robot.end());
    sortFactoryByFirst(factory);
    vector<vector<int64_t>> dp(n, vector<int64_t>(m));
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            int64_t ans = INT64_MAX;
            if (j > 0) {
                ans = dp[i][j - 1];
            }
            int64_t distance = 0;
            for (int l = i, num = 1; l >= 0 && num <= factory[j][1]; l--, num++) {
                int64_t curAns = 0;
                if (l - 1 < 0) {
                    curAns = 0;
                }
                else if (j - 1 < 0) {
                    curAns = INT64_MAX;
                }
                else {
                    curAns = dp[l - 1][j - 1];
                }
                distance += abs(robot[l] - factory[j][0]);
                if (curAns != INT64_MAX) {
                    ans = min(ans, curAns + distance);
                }
            }
            dp[i][j] = ans;
        }
    }
    return dp[n - 1][m - 1];
}

int64_t minimumTotalDistance3(vector<int>& robot, vector<vector<int>>& factory, int n, int m) {
    sort(robot.begin(), robot.end());
    sortFactoryByFirst(factory);
    vector<vector<int64_t>> dp(n, vector<int64_t>(m, INT64_MAX));
    vector<Pair> deque(n + 1);
    int l = 0, r = 1;
    deque[0].x = -1;
    deque[0].y = 0;
    for (int j = 0; j < m; j++) {
        int64_t add = 0;
        int64_t limit = (int64_t)factory[j][1];
        l = 0;
        r = 1;
        deque[l].x = -1;
        deque[l].y = 0;
        for (int i = 0; i < n; i++) {
            int64_t p1 = INT64_MAX;
            if (j > 0) {
                p1 = dp[i][j - 1];
            }
            add += abs(robot[i] - factory[j][0]);
            while (l < r && deque[l].x == (int64_t)i - limit - 1) {
                l++;
            }
            int64_t p2 = INT64_MAX;
            if (l < r) {
                int64_t best = deque[l].y;
                if (best != INT64_MAX) {
                    p2 = add + best;
                }
            }
            dp[i][j] = min(p1, p2);
            int64_t fill = p1;
            if (p1 == INT64_MAX) {
                fill = p1;
            }
            else {
                fill = p1 - add;
            }
            while (l < r && deque[r - 1].y >= fill) {
                r--;
            }
            deque[r].x = i;
            deque[r].y = fill;
            r++;
        }
    }
    return dp[n - 1][m - 1];
}

int main() {
    if (true) {
        vector<int> robot{ 0, 4, 6 };
        vector<vector<int>> factory{ {2, 2}, {6, 2} };
        int n = robot.size();
        int m = factory.size();
        vector<vector<int64_t>> dp(n, vector<int64_t>(m, -1));
        printf("%lld\n", minimumTotalDistance1(robot, factory, n - 1, m - 1, dp));
    }
    if (true) {
        vector<int> robot{ 0, 4, 6 };
        vector<vector<int>> factory{ {2, 2}, {6, 2} };
        int n = robot.size();
        int m = factory.size();
        printf("%lld\n", minimumTotalDistance2(robot, factory, n, m));
    }
    if (true) {
        vector<int> robot{ 0, 4, 6 };
        vector<vector<int>> factory{ {2, 2}, {6, 2} };
        int n = robot.size();
        int m = factory.size();
        printf("%lld\n", minimumTotalDistance3(robot, factory, n, m));
    }
    return 0;
}

在这里插入图片描述

c语言的不好写,故没有代码。

标签:deque,int,机器人,factory,robot,dp
From: https://www.cnblogs.com/waitmoon/p/17378689.html

相关文章

  • 零代码基础,一分钟教你快速搭建微信ChatGPT机器人!
    本教程收集于:ChatGPT聊天机器人搭建全攻略汇总:精心整理Github登录账号后,先Forck下仓库:https://github.com/zhayujie/chatgpt-on-wechat功能介绍:多端部署:有多种部署方式可选择且功能完备,目前已支持个人微信,微信公众号和企业微信应用等部署方式基础对话:私聊及群聊的消息智能......
  • WCF Error : Manual addressing is enabled on this factory, so all messages sent m
    WCFError:Manualaddressingisenabledonthisfactory,soallmessagessentmustbepre-addressed 回答2Iaddedaservicereferenceasusualandgotthiserror.TurnsoutallIhadtodowastoamendtheclientconfigtouseanendpointconfigwitha......
  • 记安装mirai qq聊天机器人
    day1:先把mirai下了下来。又装个运行时环境,原来玩mc装了个jvav8,但是不行,上这里下了一个java17。因为在安装程序里装好像有bug,下下来是个什么鬼玩意不知道。然后就照着教程安,然后就成功了。话说我原来开博客是想要写题解欸(......
  • [Leetcode] 0657. 机器人能否返回原点
    657.机器人能否返回原点题目描述在二维平面上,有一个机器人从原点(0,0)开始。给出它的移动顺序,判断这个机器人在完成移动后是否在 (0,0)处结束。移动顺序由字符串 moves 表示。字符move[i]表示其第i次移动。机器人的有效动作有 R(右),L(左),U(上)和D(下)。如果机器人在完......
  • SqlSessionFactory、SqlSession、Druid之间的关系梳理
    SqlSessionFactory是什么?SqlSessionFactory 是Mybatis的核心接口之一,它是用于创建SqlSession对象。Mybatis的SqlSession对象是负责管理应用程序与数据库之间一组事务的机制,并为应用程序提供访问数据库的方法。SqlSession是线程不安全的对象,因此应始终使用它的请求/响......
  • 魔兽服务端编译部署NPCBots和机器人模块教程
    魔兽服务端编译部署NPCBots和机器人模块教程大家好,我是艾西。在平时自己一个人玩魔兽的时候是不是会比较无聊,因为游戏机制或副本难度自己一个人无法进行快乐的玩耍。今天艾西教大家编译部署NPCBots和Al机器人模块,直接一个人玩魔兽也不孤单首先到GIT去下载ai机器人以及bots模块解压......
  • 简单工厂模式(Static Factory Method)
    创建性设计模式——简单工厂模式(StaticFactorymethod)模式动机只需要知道参数的名字则可得到相应的对象软件开发时,有时需要创建一些来自于相同父类的类的实例。可以专门定义一个类(工厂)负责创建这些类的实例。可以通过传入不同的参数从而获得不同的对象。Java中可以将创建其......
  • cpp: Abstract Factory Pattern
     //Gold.h:此文件包含"Gold"类。AbstractFactoryPatternC++14//2023年4月30日涂聚文GeovinDuVisualStudio2022edit.#pragmaonce#ifndefGOLD_H#defineGOLD_H#include<iostream>usingnamespacestd;namespaceDuJewelryAbstra......
  • 工厂方法与FactoryBean
    概述工厂方法是比较常见,常用的一种设计模式。FactoryBean是Spring提供的一种Bean注入IOC容器的方式。工厂方法在做日常开发时,一般都会避免直接new对象,而且将new的操作丢给IOC容器,但对于第三方系统的集成,我们不太好直接丢给IOC容器,此时可以通过工厂模式,提供一个工厂类来实例化......
  • No service of type Factory<LoggingManagerInternal> available in ProjectScopeServ
    最近从GitHub上down下来一个项目,却在导入到AS的时候一直报Error:NoserviceoftypeFactory<LoggingManagerInternal>availableinProjectScopeServices.这个错误clean一下项目之后,报出了详细错误信息接下来仔细看异常信息,Couldnotcreatepluginoftype'AndroidMavenPlugin......