有n个盒子排成了一行,每个盒子上面有一个数字a[i],表示在该盒子上的人最多能向右移动a[i]个盒子(比如当前所在盒子上的数字是3,则表示可以一次向右前进1个盒子,2个盒子或者3个盒子)。
从左边第一个盒子上开始体验游戏,请问最少需要移动几次能到最后一个盒子上?
备注:如果没有盒子或跳不到最后一个盒子上,则返回-1;如果已经在最后盒子上,则直接返回0。
递归
int _solution(int a[], int start, int N)
{
if(start == N - 1) return 0;//最后一个盒子,结束递归
if(start > N-1) return N + 1;//超出数组边界则返回一个较大的值
int step = N + 1;//初始设置一个较大的值
int steps = a[start];//此时可以跳的最大步数
for(int i = 1; i <= steps; i++)
{
step = min(step, _solution(a, start + i, N));//递归循环
}
return step + 1;
}
int solution(int a[], int N)//N个盒子,盒子编码储存在a[]
{
if(N == 0 || N == 1) return 0;
int count = _solution(a, 0, N);
if(count <= N)//最多N步
return count;
else
return -1;
}
动态规划
int solution(int a[], int N)//N个盒子,盒子编码储存在a[]
{
if(N == 0 || N == 1) return 0;
int dp[N];
for(int i = 0; i < N; i++){
int maxPos = min(N - 1, i + a[i]);
for(int j = i + 1; j <= maxPos; j++)
if(dp[j] == 0) dp[j] = dp[i] + 1;
}
int count = dp[N - 1];
return count ? count : -1;
}