2017.5.7 过河 失败总结

来源:互联网 发布:关于套路的网络新词 编辑:程序博客网 时间:2024/06/03 12:57

        这个题非常的坑、、只能想到nT做法、感觉中途肯定有很多费步、而且石子非常少,可以想到围绕石子走、但石子前的必须递推来、

        好吧,其实这个题,只需要对每个位置判断,没有必要每条路走下去、、就是说你只需要看这个点可不可以被前面的所有点更新到即可,


即对于s到t这些数   从原点开始  找到一个距离范围(大于等于某个值),使这个范围内所有的数都可以被原点以左的点   +几个(s到t之间的数) 得到、 

 设这个范围为p,则>p的和=p的都是被全部原点以左的数转移、显然=p的步数最少、

      例如对于s=3,t=5;

          

这个限度很显然是  s*(s-1)   因为对于小于s*(s-1)的数,它不能由最小的s补起来

但如果是s==t   那这个坑是永远填不上的、因为只有一个数,肯定有空隙

码:

#include<iostream>#include<cstdio>using namespace std;#include<algorithm>#include<cstring>int l,s,t,n,i,a[100005],f[100005],ans,b[100005],j;bool lei[100005];int main(){scanf("%d%d%d%d",&l,&s,&t,&n);for(i=1;i<=n;i++)scanf("%d",&a[i]);if(s==t){for(i=1;i<=n;i++)if(!(a[i]%s))++ans;cout<<ans;return 0;}sort(a+1,a+1+n);if(a[1]>100)b[1]=100;else b[1]=a[1];for(i=2;i<=n;i++)if(a[i]>a[i-1]+100)b[i]=b[i-1]+100;else b[i]=b[i-1]+(a[i]-a[i-1]);for(i=1;i<=n;i++)lei[b[i]]=1;ans=1e8;l=b[n]+t;memset(f,0x7f,sizeof(f));f[0]=0;for(i=s;i<=l;i++){for(j=s;j<=t;j++){if(i-j<0)break;f[i]=min(f[i],f[i-j]);}if(lei[i])f[i]+=1;}for(i=b[n];i<=l;i++)ans=min(ans,f[i]);cout<<ans;} 









0 0