// Based on "Optimal k-means Clustering in One Dimension by Dynamic Programming" // (https://journal.r-project.org/archive/2011-2/RJournal_2011-2_Wang+Song.pdf) import java.util.*; import java.io.*; public class Broadband { public static void main(String[] args) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); int n, m, k, s; double x[]; StringTokenizer st = new StringTokenizer(in.readLine()); m = Integer.parseInt(st.nextToken()); n = Integer.parseInt(st.nextToken()); k = Integer.parseInt(st.nextToken()); s = Integer.parseInt(st.nextToken()); x = new double[m+n+1]; st = new StringTokenizer(in.readLine()); for (int i = 1; i <= m; i++) { x[i] = Double.parseDouble(st.nextToken()); } st = new StringTokenizer(in.readLine()); for (int i = m+1; i <= m+n; i++) { x[i] = Double.parseDouble(st.nextToken()); } Arrays.sort(x); // omit if data are already sorted n = m+n; // Pre-calculate means of all sets {x[i], ..., x[j]} double mu[][] = new double[n+1][n+1]; for (int i = 1; i <= n; i++) { mu[i][i] = x[i]; for (int j = i+1; j <= n; j++) { mu[i][j] = (x[j] +(j-i)*mu[i][j-1])/(j-i+1); } } // Pre-calculate sums of squares of x[i]-mu[i,j], ..., x[j]-mu[i,j] // for all i<= j using nifty formula from aforementioned reference double d[][] = new double[n+1][n+1]; for (int i = 1; i <= n; i++) { d[i][i] = 0; for (int j = i+1; j <= n; j++) { d[i][j] = d[i][j-1]+(j-i)*1.0/(j-i+1)*Math.pow(x[j]-mu[i][j-1],2); } } // Dynamic programming: D[i][m] = best sum of squared distances for // x[1] ..., x[i] using m sets (I'm using notation from the paper; // this "m" is just an index variable, not the same as the input value m, // which has already been incorporated into a new value for n.) double D[][] = new double[n+1][k+1]; for (int i = 1; i <= n; i++) { D[i][1] = d[1][i]; } for (m = 2; m <= k; m++) { for (int i = 1; i <= n; i++) { double min = Double.MAX_VALUE; for (int j = m; j<= i; j++) { double t = D[j-1][m-1]+d[j][i]; if (t < min) min = t; } D[i][m] = min; } } // Above used only horizontal differences in location. // Finally, add in squares of vertical distances which are all // identical and equal to (s/2)^2. System.out.println(D[n][k]+n*Math.pow(s/2.0,2)); } }