题目描述
题目分析
这题是典型的需要用到动态规划来求解的题目,试着这样想,wzy一次可以跨的最大的步数为k,也就是说他一次可以跨1步,也可以跨2步,即他一次可以跨不大于k的任意步数,那么wzy到达位置n处就有k种方法,即它可以在位置n-k处一次跨k步到达位置n,也可以在位置n-k-1处一次跨k-1步到达位置n........以此类推它还可以在位置n-1处一次跨1步到达位置n,所以wzy到达位置n处时的前一种位置状态的可能情况有k种,即它到达位置n的前一个位置可能为n-k~n-1的任意一个,即k个状态。若要wzy到达位置n时所踩的水坑的个数最少,那么,它到达位置n的前一个位置时所踩的水坑也应该是最少的,若我们用一个数组rec来记录wzy到达位置i处时所踩的最少的水坑数目,即rec[i]表示wzy到达位置i处时所踩的最少的水坑数,那么rec[n]=min{rec[n-k],rec[n-k+1],rec[n-k+2]..........rec[n-1]}+1/0;是否加1取决于位置n处是否存在水坑,若位置n处存在水坑,那么就要加1,否则就不加1;所以根据这个思路很容易就可以写出代码,程序源代码以及运行结果截图如下:
程序源代码
//wzy的跑步
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int runway[10001] = { 0 };
int pool[10001] = { 0 }; //表示水坑的位置;
int rec[10001] = { 0 }; //用于记录到达位置i时最少所需要踩的水坑数,如rec[2]表示其到达位置2时所踩的最少的水坑数;
int main()
{
int n; //n表示跑道的长度
int m; //表示共有m个水坑
int k; //表示wzy一次可以跨越的最大步数
while (scanf("%d%d%d", &n, &m, &k) != EOF)
{
for (int i = 1; i <= m; i++)
{
scanf("%d", &pool[i]);
runway[pool[i]] = -1; //用-1表示这个位置处存在水坑
}
for (int i = 1; i <= n; i++)
{
if (i == 1)
{
if (runway[i] == 0)
{
rec[i] = 0;
}
else
{
rec[i] = 1;
}
}
else if (i >= 2)
{
//解题思路:若要wzy到达位置n时所踩的水坑的个数最少,那么,它到达位置n的前一个位置时所踩的水坑也应该是最少的,
//若我们用一个数组rec来记录wzy到达位置i处时所踩的最少的水坑数目,即rec[i]表示wzy到达位置i处时所踩的最少的水坑数,
//那么rec[n]=min{rec[n-k],rec[n-k+1],rec[n-k+2]..........rec[n-1]}+1/0;
//是否加1取决于位置n处是否存在水坑,若位置n处存在水坑,那么就要加1,否则就不加1;
int min ; //以下代码的作用是用于求min{rec[n-k],rec[n-k+1],rec[n-k+2]..........rec[n-1]}
if (i - k >= 1)
{
min = rec[i - k];
for (int j = i-k; j < i; j++)
{
if (rec[j] < min)
{
min = rec[j];
}
}
}
else
{
min = rec[1];
for (int j = 1; j < i; j++)
{
if (rec[j] < min)
{
min = rec[j];
}
}
}
if (runway[i] == 0)
{
rec[i] = min;
}
else
{
rec[i] = min + 1;
}
}
}
printf("%d\n", rec[n]);
}
return 0;
}
运行结果截图
我后面会更新动态规划法的详细介绍,以及常见的可以用动态规划法来解决的题目,感兴趣的话可以关注一下