https://www.luogu.com.cn/problem/P1052
设f[i]表示到达i位置最少踩到石子个数
f[i]从f[i-t]到f[i-s]转移
但是l太大要压缩路径
1.根据小凯的疑惑中的结论
方程px+(p+1)y=z,当z>=p(p+1)-p-(p+1)时一定有解
在本题中步数最多为10,即p+1最多为10
所以当两点距离大于等于72时一定能从前一个点到后一个点
我们可以把这样的两个点的距离直接变成72
即把所有石子的距离模73
注意原题中s可以等于t,这时不存在p和p+1两种决策
所以需要特判一下,s=t&&石子坐标%s=0答案加一
2.https://www.luogu.com.cn/blog/yzp2846799957/solution-p1052
在s和t的最小公倍数之后的点都可以走到
可以用s*t缩点
或者1~10的最小公倍数2520缩点
3.随便用个大一点而且不会t的数缩点,,用了1000没有特判,,不知道为什么ac了,,,
#include<bits/stdc++.h>
using namespace std;
int a[1000000],dp[1000000],tt[1000000];
bool cmp(int x,int y)
{
return x<y;
}
int main()
{
int l,s,t,x,sum=0,m,ans=0x3f3f3f3f;
memset(dp,0x3f,sizeof(dp));
memset(a,0,sizeof(a));
cin>>l>>s>>t>>m;
for(int i=1;i<=m;i++)
{
cin>>a[i];
}
if(s!=t)
{
sort(a+1,a+1+m,cmp);
for(int i=0;i<m;i++)
{
if(a[i+1]-a[i]>1000) sum=(a[i+1]-a[i])/1000*1000;
a[i+1]-=sum;
tt[a[i+1]]=1;
}
if(l-a[m]>1000) l-=(l-a[m])/1000*1000;
dp[0]=0;
for(int i=1;i<=l+t;i++)
{
for(int j=max(0,i-t);j<=i-s;j++)
if(tt[i]) dp[i]=min(dp[i],dp[j]+1);
else dp[i]=min(dp[i],dp[j]);
//QAQif(a[i]) dp[i]++;
}
for(int i=l;i<=l+t;i++)
{
ans=min(ans,dp[i]);
}
cout<<ans;
}
else
{
ans=0;
for(int i=1;i<=m;i++) if(a[i]%s==0) ans++;
cout<<ans;
}
return 0;
}
hack
https://www.luogu.com.cn/discuss/show/29232
缩点的过程中把一个区间变成了一个点,如果x,y都是石子,本来可以从x-1转移到y-1在缩点后必须要踩石子,也许可以特判一下?不懂QAQ