题意:
给你一个地图,问从x1,y1->x2,y2,要走的路最短,问
耗油和速度
题解:
首先把他们转到左下角->右上角
然后只能往上或往下
考虑到可能有小数
所以都乘上他们的公倍数
然后就是dp
代码:
#include<bits/stdc++.h> using namespace std; const int N=12,M=210005; const double inf=1e15; int n,L,lcm,lim,i,j,k,p,x,y,a[N],b[N],xs,ys,xt,yt,t1,t2,ans1=-1,ans2; double f[2][N][M],w[N]; int gcd(int a,int b){return b?gcd(b,a%b):a;} void up(double&a,double b){if(a>b)a=b;} int cal(int x) { x*=12; return x/lcm+(x%lcm>0); } int main() { scanf("%d%d",&n,&L); for (int i=1;i<=10;i++)w[i]=1.0*L/(80.0-0.75*i*i); for (int i=1;i<=n;i++)scanf("%d",&a[i]),a[i]/=5; for (int i=1;i<=n;i++)scanf("%d",&b[i]),b[i]/=5; for (int i=1;i<=n;i++)x=max(max(a[i],b[i]),x); for (int i=lcm=1;i<=x;i++)lcm=lcm*i/gcd(lcm,i); scanf("%d%d%d%d%d%d",&xs,&ys,&xt,&yt,&t1,&t2); lim=t2*lcm/12; if (xs>xt)swap(xs,xt),swap(ys,yt); if (ys>yt) { for (int i=1,j=n;i<j;i++,j--)swap(a[i],a[j]); ys=n-ys+1,yt=n-yt+1; } for (int j=ys;j<=yt;j++) for (int k=0;k<=lim;k++)f[0][j][k]=inf; f[0][ys][0]=0; for (int i=xs;i<=xt;i++,p^=1) { for (int j=ys;j<=yt;j++) for (int k=0;k<=lim;k++)f[p^1][j][k]=inf; for (int j=ys;j<=yt;j++) for (int k=0;k<=lim;k++) if (f[p][j][k]<inf) { if (j<yt) for (int x=b[i];x;x--) { y=k+lcm/x*L; if (y<=lim)up(f[p][j+1][y],f[p][j][k]+w[x]); } if (i<xt) for (int x=a[j];x;x--) { y=k+lcm/x*L; if (y<=lim)up(f[p^1][j][y],f[p][j][k]+w[x]); } } } for (int k=0;k<=lim;k++) if (k*12>=t1*lcm&&f[p^1][yt][k]<inf) { if (ans1<0)ans1=k; if (!ans2||f[p^1][yt][k]+1e-9<f[p^1][yt][ans2])ans2=k; } if (ans1<0) { puts("No"); return 0; } printf("%d %.2f %d %.2f",cal(ans1),f[p^1][yt][ans1], cal(ans2),f[p^1][yt][ans2]); return 0; }