2017.5.7 过河 失败总结

xiaoxiao2021-02-28  99

        这个题非常的坑、、只能想到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; }

转载请注明原文地址: https://www.6miu.com/read-72441.html

最新回复(0)