题解:本题主要考查dp+路径压缩。
简要题意:有一条米长的桥,桥上有个石头。小青蛙从桥头开始,向终点跳。跳跃距离为到,求青蛙最少需要踩到的石子数。
1.dp:本题的难点不在dp的转移方程上,易得出:设为在上经过的石头数
位置上有石头:
位置上无石头:
2.路径压缩:本题的规模极大,但很小,所以就需要巧妙的路径压缩。我们发现以后的每个点都可以到达, 所以我们只需将每两个石头超过的距离缩成就可以了
代码如下:
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int stone[233333],v[999999],f[233333],a[233333];
int n,s,t,m,ans=0x3f3f3f,d;
int main()
{
cin>>n>>s>>t>>m;
for(int i=1;i<=m;i++)cin>>stone[i];
sort(stone+1,stone+m+1);
if(s==t)
{
int sum=0;
for(int i=1;i<=m;i++)
if(stone[i]%s==0)sum++;
cout<<sum<<endl;cin>>n;
return 0;
}
for(int i=1;i<=m;i++)
{
d=stone[i]-stone[i-1];
if(d>s*t)d=s*t;
a[i]=a[i-1]+d;
v[a[i]]=1;
}
if(a[m]+s*t<n)
n=a[m]+s*t;
memset(f,0x3f3f3f,sizeof(f));
f[0]=0;
for(int i=1;i<=n;i++)
for(int j=s;j<=t;j++)
if(i>=j)
{
if(v[i]==1)f[i]=min(f[i],f[i-j]+1);
else f[i]=min(f[i],f[i-j]);
}
for(int i=1;i<=n;i++)
ans=min(ans,f[n]);
cout<<ans<<endl;
return 0;
}
来源:https://blog.csdn.net/wly1127/article/details/102759517