一条直线上有居民点,邮局只能建在居民点上。给定一个有序整形数组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]); } }