牛客 过河(dp)
这道题初始方程很简单,但是数据很大,因此我们想到,如果缩一下距离,一看到st是1-10,就很有可能跟他的最小公倍数有关,很多题目都是可以猜出来,因为1-10是一个很神奇的数字
所以,2520这个距离是可以到达的,我们只需要将两者之间的距离模2520,就成功缩小了。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<functional> #include<string> #include<algorithm> #include<iostream> #include<set> #include<vector> #include<queue> #include<cstdlib> using namespace std; const int N=3e5+10; int a[N]; int dis[N]; int vis[N]; int f[N]; int main(){ int l; cin>>l; int s,t,m; cin>>s>>t>>m; int i; for(i=1;i<=m;i++){ cin>>a[i]; } if(s==t){ int cnt=0; for(i=1;i<=m;i++){ if(a[i]%t==0) cnt++; } cout<<cnt<<endl; return 0; } sort(a+1,a+1+m); for(i=1;i<=m;i++){ dis[i]=(a[i]-a[i-1])%2520; } for(i=1;i<=m;i++){ a[i]=a[i-1]+dis[i]; vis[a[i]]=1; } l=a[m]; memset(f,0x3f,sizeof f); f[0]=0; for(i=1;i<=l+t-1;i++){ for(int j=s;j<=t;j++){ if(i>=j){ f[i]=min(f[i],f[i-j]+vis[i]); } } } int ans=1e9; for(i=l;i<=l+t-1;i++){ ans=min(ans,f[i]); } cout<<ans<<endl; }
没有人不辛苦,只有人不喊疼