http://codeforces.com/contest/489/problem/E
https://www.cnblogs.com/KirisameMarisa/p/4187637.html
1 import java.util.Scanner;
2
3 import static java.lang.Math.abs;
4 import static java.lang.Math.sqrt;
5
6 public class main2 {
7 static Scanner io = new Scanner(System.in);
8 static final int maxn = 1050, INF = (int) 1e9;
9 static final double Eps = 1e-9;
10
11 static int[] x = new int[maxn];
12 static int[] p = new int[maxn];
13
14 static int[] pre = new int[maxn];
15
16 static int n, L;
17
18
19 public static void main(String[] args) {
20 n = io.nextInt();
21 L = io.nextInt();
22 for (int i = 1; i <= n; i++) {
23 x[i] = io.nextInt();
24 p[i] = io.nextInt();
25 }
26
27 //Dinkelbach
28 double ans = 1, tmp = 0;
29 double[] d = new double[maxn];
30 while (abs(ans - tmp) > Eps) {
31 ans = tmp;
32
33 //博客的原话是“把最大的K个d[i]加起来就完事了”
34 //本题中只要d[i]>0就可以加起来,具备最优子结构,变成了简单的动态规划。而原题是不具备的
35
36 for (int i = 1; i <= n; i++) {
37 //本题求的是最小值,博客里是最大值,所以初始化要大,更新要小
38 d[i] = INF;
39 for (int j = 0; j < i; j++) {
40 if (d[i] > d[j] + sqrt(abs(x[i] - x[j] - L)) - tmp * p[i]) {
41 d[i] = d[j] + sqrt(abs(x[i] - x[j] - L)) - tmp * p[i];
42 pre[i] = j;
43 }
44 }
45 }
46
47 a=b=0;
48 add(n);
49 tmp = a/b;
50 }
51
52 printt(n);
53 }
54
55 static int a, b;
56
57 static void add(int n) {
58 if (n == 0) return;
59 a += sqrt(abs(x[n] - x[pre[n]]-L));
60 b += p[n];
61 add(pre[n]);
62 }
63
64 static void printt(int n){
65 if (n==0)return;
66 printt(pre[n]);
67 System.out.print(n+" ");
68 }
69 }