正在学习递归算法, 算法题意如下:
假设有排成一行的n个位置, 即为1到n, n一定是大于或是定义2的值.
开始的时候机器人在其中的m位置上,m一定是1~n中的一个
如果机器人来到1位置,下一步只能往右来到2位置;
若在n位置, 下一步只能往左来到n-1位置
若在中间,下一步可以选择往左或是往右走
若规定机器人必须走k步, 最终来到p位置(p在1~n中), 每步只能走1个位置
给定4个参数n, m, k, p . 返回可行的方法数
#include "stdafx.h"
#include <iostream>
//当前位置与剩余步数的值,也用于确定数组大小
#define M 5
#define K 5
int walkCache(int n, int cur, int rest, int p, int dp[][K + 1]){
if (dp[cur][rest] != -1){ //如果dp已经更新,直接返回
return dp[cur][rest];
}
if (rest == 0){ //结束标志
dp[cur][rest] = cur == p ? 1 : 0;
return dp[cur][rest];
}
if (cur == 1){ //左边界
dp[cur][rest] = walkCache(n, 2, rest - 1, p, dp);
return dp[cur][rest];
}
if (cur == n){ //右边界
return walkCache(n, n - 1, rest - 1, p, dp);
}
//中间
dp[cur][rest] = (walkCache(n, cur + 1, rest - 1, p, dp) + walkCache(n, cur - 1, rest - 1, p, dp));
return dp[cur][rest];
}
int waysCache(int n, int m, int k, int p){
if (n < 2 || k < 1 || m < 1 || m> n || p < 1 || p > n){
return 0;
}
int dp[M + 1][K + 1];
memset(dp, -1, sizeof(dp));
return walkCache(n, m, k, p, dp);
}
int main(){
std::cout << waysCache(10, M, K, 6);
}
代码可以运行,但结果出错, 调试过程中发现
每次执行到 (walkCache(n, cur + 1, rest - 1, p, dp) + walkCache(n, cur - 1, rest - 1, p, dp))
就会返回一个较大的值给dp[cur][rest], 在最后dp[cur][rest]的值会变的很大, 越界成为负数.
期望返回一个int, 表示当前状态的可行方法数.
我不太清楚是递归思路算法错误,还是具体的代码出现了错误.
我写的和你写的略有不同,但都是递归,你可以参考一下我写的
#include <iostream>
int walk_start(int n,int m,int k,int p);
int walk_left(int n,int m,int k,int p);
int walk_right(int n,int m,int k,int p);
int sum=0;
using namespace std;
int main()
{
int n,m,k,p;
cin >> n >> m >> k >> p;
walk_start(n,m,k,p);
cout << sum << endl;
return 0;
}
int walk_start(int n,int m,int k,int p)
{
walk_left(n,m,k,p);
walk_right(n,m,k,p);
return sum;
}
int walk_left(int n,int m,int k,int p)
{
k--;
m--;
if(k==0&&m==p)
return sum++;
else if(k==0&&m!=p)
return 0;
else if(k!=0&&m<1)
return 0;
else
{
walk_left(n,m,k,p);
walk_right(n,m,k,p);
return 0;
}
}
int walk_right(int n,int m,int k,int p)
{
k--;
m++;
if(k==0&&m==p)
return sum++;
else if(k==0&&m!=p)
return 0;
else if(k!=0&&m>n)
return 0;
else
{
walk_left(n,m,k,p);
walk_right(n,m,k,p);
return 0;
}
}