luogu P4677 山区建小学

题目描述

政府在某山区修建了一条道路,恰好穿越总共nnn个村庄的每个村庄一次,没有回路或交叉,任意两个村庄只能通过这条路来往。已知任意两个相邻的村庄之间的距离为did_idi​(为正整数),其中,0<i<n0<i<n0<i<n。为了提高山区的文化素质,政府又决定从nnn个村中选择mmm个村建小学。请根据给定的nnn、mmm以及所有相邻村庄的距离,选择在哪些村庄建小学,才使得所有村到最近小学的距离总和最小,计算最小值。。

输出格式

各村庄到最近学校的距离之和的最小值。

输入格式

第1行为n和m,其间用空格间隔。

第2行为n-1个整数,依次表示从一端到另一端的相邻村庄的距离,整数之间以空格间隔。

各村庄到最近学校的距离之和的最小值。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=505;
int a[N],dp[N][N],f[N][N];
signed main(){
    int n,m; cin>>n>>m;
    for(int i=2;i<=n;i++)scanf("%d",&a[i]),a[i]+=a[i-1];
    for(int l=1;l<=n;l++) 
    for(int r=l;r<=n;r++){
        int mid=(l+r)>>1;
        for(int k=l;k<=r;k++)
        f[l][r]+=abs(a[mid]-a[k]);
    }
    memset(dp,0x7f,sizeof(dp));
    dp[0][0]=0;
    for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){
        if(j>i){dp[i][j]=0;continue;}
        for(int k=j-1;k<=i;k++){
            dp[i][j]=min(dp[i][j],dp[k][j-1]+f[k+1][i]);
        }
    }
    cout<<dp[n][m]<<endl;
}

猜你喜欢

转载自www.cnblogs.com/naruto-mzx/p/11891481.html
今日推荐