输入:
10 4974
3636 3
6679 70
7182 93
10618 98
14768 23
15242 99
16077 35
23368 46
27723 15
32404 81
输出:
0.465308
类似于求最小平均值问题
首先二分答案mid
然后根据一个式子:∑w/∑a[i]<=mid
∑w-mid*a[i]<=0说明答案可以更小
这个过程用一个n^2的dp实现
f[i]=min(f[i],f[j]+dis(j,i)-mid*a[i])
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 double eps=0.0000001; 8 double f[1001],x[1001],a[1001],L,inf; 9 int n; 10 double abss(double p) 11 { 12 if (p<0) return -p; 13 else return p; 14 } 15 double check(double k) 16 {int i,j; 17 f[0]=0; 18 for (i=1;i<=n;i++) 19 { 20 f[i]=inf; 21 for (j=0;j<=i-1;j++) 22 if (f[i]>f[j]+sqrt(abss(x[i]-x[j]-L))-k*a[i]) 23 f[i]=f[j]+sqrt(abss(x[i]-x[j]-L))-k*a[i]; 24 } 25 return f[n]; 26 } 27 int main() 28 {int i; 29 cin>>n>>L; 30 inf=1000000000.0; 31 for (i=1;i<=n;i++) 32 { 33 scanf("%lf%lf",&x[i],&a[i]); 34 } 35 double l=0,r=1000000.0,mid; 36 while (r-l>eps) 37 { 38 mid=(l+r)/2.0; 39 if (check(mid)<eps) r=mid; 40 else l=mid; 41 } 42 printf("%.6lf\n",r); 43 }