牛客 过河(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;
}
View Code
原文地址:https://www.cnblogs.com/ctyakwf/p/12928372.html