数轴line_#include

输入:

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 }