题目大意
一条长度为L的河,某些地方有石头,每次可以跳S~T的长度。求最少踩到几块石头。
算法
DP,f[i]=f[i-j]+flag[i]。但是河的长度有1e9,所以我们要压缩路径。
若两个石子之间的距离大于t(t-1),我们就可以把它改成t(t-1)。
然后DP就好了
代码
#include <cstdio>
#include <algorithm>
#define INF 1<<30
int a[101],dis[101],flag[10001],f[10001];
int main(){
int l,s,t,n;
scanf("%d%d%d%d",&l,&s,&t,&n);
if(s==t){
int cnt=0;
for(int i=1;i<=n;i++){
int tt;
scanf("%d",&tt);
cnt+=(tt%s==0);
}
printf("%d\n",cnt);
return 0;
}
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
std::sort(a+1,a+n+1);
dis[n+1]=std::min(l-a[n],100);
l=0;
for(int i=1;i<=n;i++){
dis[i]=std::min(a[i]-a[i-1],90);
l+=dis[i];
flag[l]=1;
}
l+=dis[n+1];
for(int i=1;i<=l+9;i++){
f[i]=INF;
for(int j=s;j<=t;j++)
if(j<=i)
f[i]=std::min(f[i],f[i-j]+flag[i]);
}
int mn=INF;
for(int i=l;i<=l+9;i++)
mn=std::min(f[i],mn);
printf("%d\n",mn);
return 0;
}
京公网安备 11010502036488号