luogu P1052 過河
阿新 • • 發佈:2018-09-19
pan \n name fine include def class $2 ...
傳送門
容易想到設\(f_i\)表示走到坐標\(i\)的最少走過的石子數
但是這題數據範圍很大,,,
不過一次可以走的步數範圍是1-10,石子個數最多100個,所以中間會有很多多出來的沒石子的路,可以考慮直接\(skipped\)掉
我們只要對每個石子之間的路程$mod$2520救星了,因為每次走1-10步都有方法走2520步
原因見下
// luogu-judger-enable-o2 #include<bits/stdc++.h> #define LL long long #define il inline #define re register #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) #define inf 999999999 using namespace std; const int N=250000+3000,M=100+10,qihoo360=2520; //2520=lcm(1,2...10) il LL rd() { re LL x=0,w=1;re char ch=0; while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();} while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();} return x*w; } int f[N],g[N],s,t,m,a[M],l; int main() { l=rd(),s=rd(),t=rd(),m=rd()+1; a[m]=l; for(int i=1;i<m;i++) a[i]=rd(); sort(a+1,a+m+1); for(int i=m;i>=1;i--) a[i]=(a[i]-a[i-1]-1)%qihoo360+1; for(int i=1;i<=m;i++) g[a[i]+=a[i-1]]=1; l=a[m],g[l]=0; for(int i=1;i<s;i++) f[i]=inf; for(int i=s;i<=l+10;i++) { f[i]=inf; for(int j=t;j>=s&&i-j>=0;j--) f[i]=min(f[i],f[i-j]+g[i]); } int ans=inf; for(int i=l;i<=l+10;i++) ans=min(ans,f[i]); printf("%d\n",ans); return 0; }
luogu P1052 過河