Luogu P1052 过河 DP

复习复习DP。。。都忘了QAQ...


好了这道题我其实是看题解才会的。。。

方程 f[i]=min(f[i-j]+v[i]) v[i]表示i是不是石头 s<=j<=t

路径压缩引用一下证明From Luogu@Panda_Hu

#include<cstdio>
#include<iostream>
#define R register int
#include<algorithm>
#define R register int
const int N=50010,Inf=0x3f3f3f3f;
using namespace std;
int l,t,s,n,mn=Inf,ans=Inf; 
int a[N],f[N],d[N],v[N];
inline int g() {
    R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar()));
    do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret;
} 
inline int min(int a,int b) {return a<b?a:b;}
signed main() {
    l=g(),s=g(),t=g(),n=g();
    if(s==t) { R cnt=0;  for(R i=1,x;i<=n;++i) x=g(),cnt+=(x%s==0);
        printf("%d\n",cnt); return 0;
    } for(R i=1;i<=n;++i) a[i]=g(); sort(a+1,a+n+1); d[n+1]=min(l-a[n],100); l=0;
    for(R i=1;i<=n;++i) d[i]=min(a[i]-a[i-1],90),l+=d[i],v[l]=1; l+=d[n+1];
    for(R i=1;i<=l+10;++i) { f[i]=Inf; 
        for(R j=s;j<=t;++j) if(i>=j) f[i]=min(f[i],f[i-j]+v[i]); 
    } for(R i=l;i<l+10;++i) ans=min(ans,f[i]); printf("%d\n",ans);
}

2019.04.28 慌得一批QAQ

猜你喜欢

转载自www.cnblogs.com/Jackpei/p/10783092.html