第一次見到這種類型的\(DP\)。。。git
方程‘:\(f[i]=min\{f[i-j]\}+Pos[i],\)若是\(i\)處有石子,\(Pos[i]=1\)。fetch
顯然會\(MLE\)。。。spa
咱們考慮狀態中那些是重複的,即咱們能夠經過一些技巧將其省掉的狀態。code
咱們發現對於一個點\(x\),對於全部的\(D\),點\(x+D(D\geq T*(T+1))\)均能從\(x\)走到。get
也就是說,這些狀態其實是一個狀態。it
因此說,咱們能夠將兩點間距離\(\geq T*(T+1)\)的變爲\(T*(T+1)\)。class
由於\(S,T\)很小,因此咱們達到了壓縮空間的目的。技巧
#include<bits/stdc++.h> using namespace std; #define int long long namespace AE86 { const int bufl=1<<15; char buf[bufl],*s=buf,*t=buf; inline int fetch() { if(s==t){t=(s=buf)+fread(buf,1,bufl,stdin);if(s==t)return EOF;} return*s++; } inline int read() { int a=0,b=1,c=fetch(); while(!isdigit(c)) b^=c=='-',c=fetch(); while(isdigit(c)) a=a*10+c-48,c=fetch(); return b?a:-a; } } const int N=1e5+10; int n,L,S,T,Dis,Sum; int Min,Pos[N],A[N],f[N]; inline void SubTask() { for(int i=1;i<=n;i++) Sum+=!(A[i]%S); printf("%lld\n",Sum); } signed main(){ #ifndef ONLINE_JUDGE freopen("A.in","r",stdin); #endif L=AE86::read(),S=AE86::read(),T=AE86::read(),n=AE86::read(); for(int i=1;i<=n;i++) A[i]=AE86::read(); sort(A+1,A+n+1); if(S==T) {SubTask();return 0;} for(int i=1;i<=n;i++) Dis=min(A[i]-A[i-1],1LL*90),Sum+=Dis,Pos[Sum]=1; Sum+=min(L-A[n],1LL*100);memset(f,0x3f,sizeof(f));Min=f[0];f[0]=0; for(int i=1;i<=Sum+9;i++) for(int j=S;j<=T;j++) if(i-j>=0) f[i]=min(f[i],f[i-j]+Pos[i]); for(int i=Sum;i<=Sum+9;i++) Min=min(Min,f[i]); printf("%lld\n",Min); }