题目:
题目给出独木桥的长度L,青蛙跳跃的距离范围s,t,桥上石子的位置。你的任务是确定青蛙要想过河,最少需要踩到的石子数。
对于每组测试数据,第一行四个正整数L, s, t, n(1 <= L <= 10^5, 1 <= s <= t <= 10,1 <= n <= 100),分别表示独木桥的长度,青蛙一次跳跃的最小距离,最大距离,及桥上石子的个数。第二行有n个不同的正整数分别表示这n个石子在数轴上的位置(数据保证桥的起点和终点处没有石子)。所有相邻的整数之间用一个空格隔开。
2 3 5 6 7
寻找青蛙最后踩到的最少的石头;
分析:
这里应该很容易想到dp,代码量也非常的简短,但是这里有一个非常坑的点,也是这个点让我卡了两个小时,所以现在决定把它记录下来。就是dp的终点,很自然的想到是l点,但是题目上说了,当青蛙跳到或跳过l点都视作青蛙跳到了终点,所以dp的终点应该是l到l+t,这样就产生了一个范围,所以最终最小值还要取一下最小。这个地方真的是有坑了,注意到这里就没有问题了。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define INF 0x3f3f3f3f
const int maxed=100000+20;
int dp[maxed],p[maxed],l,s,t,n;
int main()
{
while(scanf("%d%d%d%d",&l,&s,&t,&n)!=EOF){
memset(p,0,sizeof(p));
memset(dp,INF,sizeof(dp));
int a;
for(int i=0;i<n;i++){
scanf("%d",&a);
p[a]=1;
}
dp[0]=0;
for(int i=1;i<=l+t;i++){
for(int j=s;j<=t;j++)
if(i-j>=0)
dp[i]=min(dp[i],dp[i-j]);
if(p[i])
dp[i]+=1;
}
for(int i=l;i<=l+t;i++)
dp[l]=min(dp[l],dp[i]);
printf("%d\n",dp[l]);
}
return 0;
}