DP
DP应该比较好想,主要是怎么压缩距离。
因为L有1e9,而s和t只有10,因此我们可以考虑在s和t上做文章。压缩距离需要保证不管怎么跳,最终状态都是等价的。
设
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 1000000
using namespace std;
int s,t,l,n,lcm;
int f[MAXN+5],a[MAXN+5],st[MAXN+5];
int gcd(int a,int b){
if (!b) return a;
return gcd(b,a%b);
}
int main(){
scanf("%d%d%d%d",&l,&s,&t,&n);
lcm=1;
for (int i=s;i<=t;i++) lcm=lcm*i/gcd(lcm,i);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
sort(a+1,a+n+1);
int k=0;
for (int i=1;i<=n;i++){
int m=a[i]-a[i-1];//压缩距离
if (m>lcm) m=m%lcm+lcm;
st[k+m]=1; k+=m;
}
memset(f,0x3f,sizeof(f)); f[0]=0;
for(int i=s;i<=k+t;i++){//DP
for (int j=s;j<=t;j++)
f[i]=min(f[i-j],f[i]);
f[i]+=st[i];//st[i]表示这里是否有石头
}
int ans=1e8;
for (int i=k;i<=k+t;i++)//因为有可能跳出,因此最后需要统计到k+t
ans=min(ans,f[i]);
printf("%d\n",ans);
return 0;
}
作者:a1799342217 发表于2017/10/31 7:12:44 原文链接
阅读:17 评论:0 查看评论