给出此problem:
您有一个仓库,其中M个容器装满了无限数量 糖果。容器均匀地排成一行 间隔为1米。您也有2个可以捡起的机器人 1块糖果,然后在任何两个容器之间运输。
机器人以两种形式的查询形式接受指令 整数,分别为Ma和Mb。要执行查询,机器人会前往 容器Ma,拿起1个糖果,将其运输到容器Mb,然后 停在Mb,直到收到另一个查询为止。
计算机器人执行必须行进的最小总距离 依次查询N个。
注意:您可以选择由哪个机器人执行每个查询。
最初,我认为我应该只是选择更接近执行移动操作的机器人,但是这种方法在某些测试用例中会失败,有人可以解释为什么这种方法不适用于所有情况,什么是正确的方法,谢谢。
样本输入和预期输出here。
答案 0 :(得分:1)
问题出在动态编程类别中,您自己标记了问题greedy
(您的做法确实很贪婪)。在某些情况下,给定查询的最小距离(局部最小)对于整个查询集(全局最小)不是最佳的。因此,您需要考虑将所有可能的机器人分配给查询,但是使用DP技术并不是一个详尽的搜索。
我不想为您详细说明确切的解决方案,因为DP上有大量在线资源(制作二维成本表,跨列=机器人1,跨行=机器人2,查找通过表格的最佳路径,…)。但我想向您展示一个示例示例,其中贪婪方法不是最优的。
A
机械手1 B
机械手2 F
查询的起点T
查询的终点用贪婪的方法解决:
(A) B
1 . . F . T . . . . . . // A is closer to F, travels 2 (to F) + 2 (to T) = 4
(A) B
2 . . . . . . F . T . . // A is closer to F, travels 2 (to F) + 2 (to T) = 4
(A) B
3 F T . . . . . . . . . // A is closer to F, travels 8 (to F) + 1 (to T) = 9
A B
总行驶距离:4 + 4 + 9 = 17
。
一种最佳方法(可能有多种):
(A) B
1 . . F . T . . . . . . // A takes query, travels 2 (to F) + 2 (to T) = 4
A (B)
2 . . . . . . F . T . . // B takes query, travels 4 (to F) + 2 (to T) = 6
(A) B
3 F T . . . . . . . . . // A takes query, travels 4 (to F) + 1 (to T) = 5
A B
总行驶距离:4 + 6 + 5 = 15
。
请注意,B
进行了第二次查询,即使它离起点的距离最近。
答案 1 :(得分:0)
在C ++中使用动态编程的工作代码(如AurelBílý所述):
#include <bits/stdc++.h>
using namespace std;
vector <pair <int,int > > input;
int dp[1002][1002];
int m,n;
int dis(int a,int b)
{
if(a == 0) return abs(input[b-1].first-input[b-1].second);
return abs(input[a-1].second-input[b-1].first)+abs(input[b-1].first-input[b-1].second);
}
int func(int i,int j)
{
if(i+1 == n+1 || j+1 == n+1)
{
return 0;
}
//cout<<i<<" "<<j<<endl;
if(dp[i][j] != -1)
return dp[i][j];
int result = INT_MAX;
result = min(func(i,j+1)+dis(j,j+1),func(j,j+1)+dis(i,j+1));
return dp[i][j] = result;
}
int main()
{
int t;cin>>t;
while(t--)
{
cin>>m>>n;
input.clear();
input.resize(n);
for(int i=0;i<n;i++)
{
int a,b;
cin>>a>>b;
input[i] = make_pair(a,b);
}
memset(dp,-1,sizeof(dp));
int first = abs(input[0].first-input[0].second);
// int second = abs(input[1].first-input[1].second);
int val = func(0,1)+first;
cout<<val<<endl;
}
return 0;
}