C++ 通过最大跳跃长度数组的最短路径
我正在调试以下问题并发布代码。不知道代码是否正确。我目前的疑问是,C++ 通过最大跳跃长度数组的最短路径,c++,algorithm,C++,Algorithm,我正在调试以下问题并发布代码。不知道代码是否正确。我目前的疑问是,i是否应该一直增加(在这一行--for(;i我在这里看到两种解决方法) 递归。简单,但效率低 您只需从索引0开始,对于每个索引i尝试跳到1到a[i]前面的索引,同时保留最后一个索引的最佳结果。它具有很高的算法复杂度,因此只有在效率真的不相关或n非常小的情况下才应选择它 算法如下所示: int best = 2147483647; vector<int> A; void Jump(int index, int step
i
是否应该一直增加(在这一行--for(;i我在这里看到两种解决方法)
递归。简单,但效率低
您只需从索引0开始,对于每个索引i
尝试跳到1到a[i]
前面的索引,同时保留最后一个索引的最佳结果。它具有很高的算法复杂度,因此只有在效率真的不相关或n
非常小的情况下才应选择它
算法如下所示:
int best = 2147483647;
vector<int> A;
void Jump(int index, int step)
{
if (step > best)
{
// for positive values, if step > best we won't improve our result
// avoid worthless calculations
return;
}
if (index == A.size() - 1)
{
if (step < best) best = step;
return;
}
int maxJumps = A[index];
for (int i = index; i <= min(index + maxJumps, A.size() - 1); i++)
{
Jump(i, step + 1);
}
}
int main()
{
// read input
Jump(0, 0);
}
vector<int> A, B;
int n;
int main()
{
// read n; read A of size n
B.reserve(n); // B should be the same size and initialized with zeroes (by default)
B[0] = 0; // not obligatory, 0 by default, just for clearness
for (int i = 0; i < n - 1; i++)
{
for (int j = i + 1; j <= min(i + A[i], n - 1); j++)
{
// improve result if we weren't there yet or if we can come to A[j]
// faster if we go from A[i]
if (B[j] == 0 || B[i] + 1 < B[j])
B[j] = B[i] + 1;
}
}
}
动态、智能、高效
这种方法使用。让我们有一个与数组A长度相同的数组B
。让B[i]
表示“跳到A[i]至少需要多少步”。如果我们知道B[i]
,那么我们可以说我们可以跳到B[i]的所有可能的索引(从i+1
到i+A[i]
)+1
。因此,您只需遍历数组,从0到N-1,然后向前看,改进每个i
到i+a[i]
的结果
大概是这样的:
int best = 2147483647;
vector<int> A;
void Jump(int index, int step)
{
if (step > best)
{
// for positive values, if step > best we won't improve our result
// avoid worthless calculations
return;
}
if (index == A.size() - 1)
{
if (step < best) best = step;
return;
}
int maxJumps = A[index];
for (int i = index; i <= min(index + maxJumps, A.size() - 1); i++)
{
Jump(i, step + 1);
}
}
int main()
{
// read input
Jump(0, 0);
}
vector<int> A, B;
int n;
int main()
{
// read n; read A of size n
B.reserve(n); // B should be the same size and initialized with zeroes (by default)
B[0] = 0; // not obligatory, 0 by default, just for clearness
for (int i = 0; i < n - 1; i++)
{
for (int j = i + 1; j <= min(i + A[i], n - 1); j++)
{
// improve result if we weren't there yet or if we can come to A[j]
// faster if we go from A[i]
if (B[j] == 0 || B[i] + 1 < B[j])
B[j] = B[i] + 1;
}
}
}
答案存储在B[n-1]
中
我已经实现了一个。我在这里看到了两种解决方法
递归。简单,但效率低
您只需从索引0开始,对于每个索引i
尝试跳到1到a[i]
前面的索引,同时保留最后一个索引的最佳结果。它具有很高的算法复杂度,因此只有在效率真的不相关或n
非常小的情况下才应选择它
算法如下所示:
int best = 2147483647;
vector<int> A;
void Jump(int index, int step)
{
if (step > best)
{
// for positive values, if step > best we won't improve our result
// avoid worthless calculations
return;
}
if (index == A.size() - 1)
{
if (step < best) best = step;
return;
}
int maxJumps = A[index];
for (int i = index; i <= min(index + maxJumps, A.size() - 1); i++)
{
Jump(i, step + 1);
}
}
int main()
{
// read input
Jump(0, 0);
}
vector<int> A, B;
int n;
int main()
{
// read n; read A of size n
B.reserve(n); // B should be the same size and initialized with zeroes (by default)
B[0] = 0; // not obligatory, 0 by default, just for clearness
for (int i = 0; i < n - 1; i++)
{
for (int j = i + 1; j <= min(i + A[i], n - 1); j++)
{
// improve result if we weren't there yet or if we can come to A[j]
// faster if we go from A[i]
if (B[j] == 0 || B[i] + 1 < B[j])
B[j] = B[i] + 1;
}
}
}
动态、智能、高效
这种方法使用。让我们有一个与数组A长度相同的数组B
。让B[i]
表示“跳到A[i]至少需要多少步”。如果我们知道B[i]
,那么我们可以说我们可以跳到B[i]的所有可能的索引(从i+1
到i+A[i]
)+1
。因此,您只需遍历数组,从0到N-1,然后向前看,改进每个i
到i+a[i]
的结果
大概是这样的:
int best = 2147483647;
vector<int> A;
void Jump(int index, int step)
{
if (step > best)
{
// for positive values, if step > best we won't improve our result
// avoid worthless calculations
return;
}
if (index == A.size() - 1)
{
if (step < best) best = step;
return;
}
int maxJumps = A[index];
for (int i = index; i <= min(index + maxJumps, A.size() - 1); i++)
{
Jump(i, step + 1);
}
}
int main()
{
// read input
Jump(0, 0);
}
vector<int> A, B;
int n;
int main()
{
// read n; read A of size n
B.reserve(n); // B should be the same size and initialized with zeroes (by default)
B[0] = 0; // not obligatory, 0 by default, just for clearness
for (int i = 0; i < n - 1; i++)
{
for (int j = i + 1; j <= min(i + A[i], n - 1); j++)
{
// improve result if we weren't there yet or if we can come to A[j]
// faster if we go from A[i]
if (B[j] == 0 || B[i] + 1 < B[j])
B[j] = B[i] + 1;
}
}
}
答案存储在B[n-1]
中
我已经实现了一个。动态规划解决方案思想:O(n^2)
假设给定的数组是A[1..n]
。从第i个位置,您可以跳转1或2或3…A[i]
。您已经计算了所有j>=i&&jDynamic编程解决方案的结果:O(n^2)
假设给定的数组是A[1..n]
。从第i个位置可以跳1或2或3…A[i]
。您已经计算了所有j>=i和&j的结果,我正在共享算法。现在,执行BFS如下所述:
int A[N]; // It contains the initial values
int result[N]; // Initialise all with positive infinty or INT_MAX in C
bool visited[N]; // Initially, all initialise with '0' means none of the index is visited
queue Q; // create a queue
index = 1
cost = 0
push index in rear of Q.
result[index] = cost
visited[index] = true
while(Q is not empty) {
index = pop the value from the front of the Q.
cost = cost + 1
for(i in 1 to A[index]) {
temp_index = index + i;
if(temp_index <= N AND visited[temp_index] == false) {
push temp_index in rear of Q.
result[temp_index] = cost
visited[temp_index] = true
}
}
}
// Finally print the value of result[N]
print result[N]
int A[N];//它包含初始值
int result[N];//使用C中的正infinty或int_MAX初始化所有
bool visted[N];//最初,使用“0”进行初始化表示未访问任何索引
队列Q;//创建一个队列
索引=1
成本=0
将索引推到Q的后面。
结果[指数]=成本
已访问[索引]=真
while(Q不是空的){
索引=从Q前面弹出值。
成本=成本+1
对于(i在1中为[索引]){
温度指数=指数+i;
如果(temp_index我正在分享算法。现在,请按以下说明执行BFS:
int A[N]; // It contains the initial values
int result[N]; // Initialise all with positive infinty or INT_MAX in C
bool visited[N]; // Initially, all initialise with '0' means none of the index is visited
queue Q; // create a queue
index = 1
cost = 0
push index in rear of Q.
result[index] = cost
visited[index] = true
while(Q is not empty) {
index = pop the value from the front of the Q.
cost = cost + 1
for(i in 1 to A[index]) {
temp_index = index + i;
if(temp_index <= N AND visited[temp_index] == false) {
push temp_index in rear of Q.
result[temp_index] = cost
visited[temp_index] = true
}
}
}
// Finally print the value of result[N]
print result[N]
int A[N];//它包含初始值
int result[N];//使用C中的正infinty或int_MAX初始化所有
bool visted[N];//最初,使用“0”进行初始化表示未访问任何索引
队列Q;//创建一个队列
索引=1
成本=0
将索引推到Q的后面。
结果[指数]=成本
已访问[索引]=真
while(Q不是空的){
索引=从Q前面弹出值。
成本=成本+1
对于(i在1中为[索引]){
温度指数=指数+i;
如果(TungEngultBTW,BFS问题不是贪婪的吗?考虑把这类问题移到CoDeEvIEW.StAccExchange。COMNO,这很好。他在问-他的方法是什么错误,而不是CoDeEvIEWO(n^ 2)。DP解决方案存在…现在你可以尝试…我有一个算法准备好了,如果我分享ITBTW,它是BFS问题不是贪婪的?考虑把这类问题移到CoDeEvIEW.StAccExchange。COMNO,这很好。他在问-他的方法是什么不对,而不是CoDeEvIEWO(N^ 2)。dp解决方案存在..您现在可以尝试..我已经准备好了一个算法,我应该分享吗it@LinMa.当前位置检查我的答案希望如此helps@LinMa.:我已经发布了一个O(n)解决方案..检查它…并确保它是正确的..如果您需要,请向我索取代码..@LinMa.:不总是移动到非零的位置…代码部分必须包含一个检查..对于0,它是一个角盒。。(除非最后一个元素跳转=0)@LinMa.:我能记住同样的逻辑让我得到一个正确的答案…只需添加一些检查0的情况。@YeldarKurmangaliyev.:检查我的算法给出正确的答案…!!@LinMa.:检查我的答案..希望如此helps@LinMa.:我已经发布了一个O(n)解决方案..检查它…并确保它是正确的..如果您需要,请向我索取代码..@LinMa.:Noways move to non zero…代码部分必须包含一个检查..对于0,它是一个角情况..(除非最后一个元素跳转=0)@LinMa.:我记得同样的逻辑给了我一个正确的答案…只需要添加一些0大小写的检查。@YeldarKurmangaliyev.:检查我的算法给出了正确的答案…!!@LinMa哦,只是一个输入错误。嗨,Yeldar,研究了你的代码,你的内部j循环代码似乎连一个[j]=0节点都没有,对吗?谢谢。@LinMa它确实:)这里:j谢谢Yeldar,我认为A[I]是0,循环的条件是false,你永远不会执行循环,”(int j=I+1;j@LinMa Yes,如果A[I]==0