一条直线上有居民点,邮局只能建在居民点上。给定一个有序整形数组arr,每个值表示居民点的一维坐标,再给定一个正数num,表示邮局数量。
选择num个居民点建立num个邮局,使所有的居民点到邮局的总距离最短,返回最短的总距离。
第一行有两个整数N,num。分别表示居民点的数量,要建的邮局数量。
接下来一行N个整数表示邮局的坐标。保证坐标递增
输出一个整数表示答案
6 2 1 2 3 4 5 1000
6
第一个邮局建立在3位置,第二个邮局建立在1000位置。那么1位置到邮局的距离为2,2位置到邮局距离为1,3位置到邮局的距离为0,4位置到邮局的距离为1,5位置到邮局的距离为2,1000位置到邮局的距离为0.
这种方案下的总距离为6。
#include <bits/stdc++.h>
using namespace std;
int main(){
int n, m, l, r, s;
cin>>n>>m;
int a[n], dp1[n][n]={0}, dp2[m][n]={0}, b[m][n]={0};
for(int i=0;i<n;i++)
cin>>a[i];
for(int i=0;i<n;i++){
dp1[i][0] = 0;
for(int j=i+1;j<n;j++)
dp1[i][j] = dp1[i][j-1] + a[j] - a[(i+j)/2];
}
for(int i=0;i<n;i++){
dp2[0][i] = dp1[0][i];
b[0][i] = 0;
}
for(int i=1;i<m;i++){
for(int j=n-1;j>i;j--){
l = b[i-1][j];
if(j==n-1)
r = n-1;
else
r = b[i][j+1];
dp2[i][j] = ~(1<<31);
for(int k=l;k<=r;k++){
s = dp2[i-1][k] + dp1[k+1][j];
if(s <= dp2[i][j]){
dp2[i][j] = s;
b[i][j] = k;
}
}
}
}
cout<<dp2[m-1][n-1]<<endl;
return 0;
} import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
public class Main {
// 题解:https://www.itdaan.com/blog/2017/11/12/363f67525ecbb9324ba4e1821281ab1b.html
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
int num = sc.nextInt();
int[] pos = new int[N];
for (int i = 0; i < N; i ++) {
pos[i] = sc.nextInt();
}
if (num >= N) {
System.out.println(0);
System.exit(0);
}
int[][] w = new int[N][N];
// w[i][j] 表示 [i,j]上建立一个邮局,最短的总距离
for (int i = 0;i < N; i ++) {
w[i][0] = 0;
for (int j = i + 1; j < N; j ++) {
w[i][j] = w[i][j-1] + pos[j] - pos[(i + j) / 2];
}
}
int[] dp = new int[N];
int[] candi = new int[N];
//dp[i][j]表示在[0,j]上建立i+1个邮局的最短总距离. dp[0][j] = w[0][j]
for (int j = 0;j < N;j ++) {
dp[j] = w[0][j];
}
for (int i = 1; i < num; i ++) {
for (int j = N-1; j > i; j--) {
int min = candi[j];
int max = j == N - 1 ? j-1 : candi[j+1];
int minValue = Integer.MAX_VALUE;
for (int k = min;k < max + 1; k ++) {
int cur = Math.max(dp[k],w[k+1][j]);
if (cur <= minValue) {
minValue = cur;
candi[j] = k;
}
}
dp[j] = minValue;
}
}
System.out.println(dp[dp.length-1]);
}
}