zoukankan      html  css  js  c++  java
  • luogu P4677 山区建小学 |dp

    题目描述

    政府在某山区修建了一条道路,恰好穿越总共nnn个村庄的每个村庄一次,没有回路或交叉,任意两个村庄只能通过这条路来往。已知任意两个相邻的村庄之间的距离为did_idi​(为正整数),其中,0<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;
    }
    
  • 相关阅读:
    (分享)视频压缩Free Video Compressor 汉化版/中文版【全网唯一】
    (分享)根据IP获取地理位置(百度API)
    易语言5.6 精简破解版[Ctoo]
    性能测试---流程篇
    性能测试--系统资源配置篇
    结合sqlmap进行sql注入过程
    MySQL使用记录
    Oracle创表操作记录
    Oracle常用函数记录
    Oracle使用记录
  • 原文地址:https://www.cnblogs.com/naruto-mzx/p/11891481.html
Copyright © 2011-2022 走看看