1197:山区建小学

简介: 1197:山区建小学

1197:山区建小学

时间限制: 1000 ms         内存限制: 65536 KB

【题目描述】

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

【输入】

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

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

例如:

10 3

2 4 6 5 2 4 3 1 3

表示在10个村庄建3所学校。第1个村庄与第2个村庄距离为2,第2个村庄与第3个村庄距离为4,第3个村庄与第4个村庄距离为6,...,第9个村庄到第10个村庄的距离为3。

【输出】

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

【输入样例】

10 2

3 1 3 1 1 1 1 1 3

【输出样例】

18

【来源】

No

1. #include<bits/stdc++.h> 
2. using namespace std;
3. int m,n,a[1000][1000],c[1000][1000],f[1000][1000];
4. int main()
5. {
6.  int i,j;
7.  cin>>m>>n;
8.  for(i=1;i<m;i++) cin>>a[i][i+1];//读入相邻村庄之间的距离 
9.  //数组a存储了每两个村庄间的距离 
10.   for(i=1;i<=m;i++)
11.     for(j=i+1;j<=m;j++)
12.       a[i][j]=a[j][i]=a[i][j-1]+a[j-1][j];
13.   //数组c存储i村到j村建立一个小学的最短距离和 
14.   for(i=1;i<=m;i++)
15.     for(j=i+1;j<=m;j++) {
16.       int mid=(i+j)/2;
17.       for(int k=i;k<=j;k++) c[i][j]+=a[k][mid];
18.     }
19.   //动规
20.   for(i=1;i<=m;i++) f[i][1]=c[1][i];
21.   for(i=1;i<=m;i++)
22.     for(j=2;j<=n;j++){
23.       f[i][j]=999999;
24.       for(int k=j-1;k<=i;k++)
25.         f[i][j]=min(f[i][j],f[k][j-1]+c[k+1][i]);
26.     }
27.   cout<<f[m][n];
28.   return 0;
29. }
1. #include <iostream>
2. #include<cmath>
3. #include<limits.h>
4. using namespace std;
5. int dp[500][500];  //动态规划 dp[m][n] 在m个村庄建n个小学的最小距离 
6. int s[500][500];   //s[i][j] 表示 从编号i村子到编号j村子里面修建1个小学的距离最小值 
7. int a[500];        // a[i]表示编号i的村子到原始村子(1号)的距离 
8. int dis(int i,int j)  //计算i号村子与j号村子的距离最小值
9. {
10.   int sum=0;
11.   int mid = (i+j)/2;
12.   for(int k=i;k<=j;k++) {
13.     sum+=abs(a[k]-a[mid]);
14.   }
15.   return sum;
16. } 
17. int min(int a,int b){
18.   return a>b?b:a;
19. }
20. int main(int argc, char *argv[])
21. {
22.   int i,j,k,m,n;
23.   cin>>m>>n;
24.   //初始化默认最大值
25.   for(i=1;i<=m;i++)
26.     for(j=1;j<=m;j++)
27.       dp[i][j]=INT_MAX;
28.   a[1]=0;  //1号村子到1号村子的距离为0 
29.   for(i=2;i<=m;i++) {
30.     cin>>a[i];     //录入当前村子的距离(距上一个村子也即是邻村)
31.     a[i]+=a[i-1];  //a[i]的结果变成了与1号村子距离 
32.   } 
33.   //将所有村子的距离计算出来
34.   for(i=1;i<m;i++)
35.     for(j=i+1;j<=m;j++)
36.       s[i][j]=s[j][i]=dis(i,j); 
37.   //初始化,建1个学校的距离
38.   for(i=1;i<=m;i++)
39.     dp[i][1]=s[1][i];
40.   //开始动态规划推算后续的数据
41.    for(j=2;j<=n;j++)  //建2个及更多的学校
42.     for(i=j;i<=m;i++) //计算前i个村子的最小距离
43.       for(k=j-1;k<i;k++)  //便利k找到j-1个学校后与i个学校之间最小距离(k在j-1与i之间) 
44.       {
45.         dp[i][j]=min(dp[i][j],dp[k][j-1]+s[k+1][i]);
46.       } 
47.   cout<<dp[m][n]<<endl; 
48.   return 0;
49. }

 

相关文章
|
6月前
|
C++
C++期末考试注意点2
C++期末考试注意点2
34 1
|
6月前
|
C++
C++期末考试注意点
C++期末考试注意点
22 0
P2433 【深基1-2】小学数学 N 合一
P2433 【深基1-2】小学数学 N 合一
284 0
广东省专升本高数考点
广东省专升本高数考点
|
运维 前端开发 Java
女生到底要不要做一个程序媛
阿粉的人缘还算是不错,毕竟是暖男一枚。前几天阿粉一个朋友来找我说,她妹妹想学编程,问我女生做一个程序媛好不好。 阿粉为了能够负责任的回答这个问题,又厚着脸皮去问了问身边的程序媛们。想到公众号的朋友们可能对这个话题也感兴趣,阿粉今天就来写一篇文章。
女生到底要不要做一个程序媛
|
算法
大一女生用数学符号作情诗赠男友 被赞“高大上”
见惯了“我爱你”、“I LOVE YOU”等示爱方式,你是否会感到审美疲劳?近日,武汉长江工商学院大一女生吴华杰用数学符号“-∞”、“+∞”和几个简单的英文单词向男友表达爱意,被同学们称赞“高端、大气、上档次”,并获得了该校举办的“三行情诗”征文比赛一等奖。
303 0
大一女生用数学符号作情诗赠男友 被赞“高大上”
|
达摩院
植树节快乐|用小学数学到高数的知识思考种树,你能种到哪一步?
今天是植树节,为了给大家的生活增加 一抹富有生机的绿色 🍃 🍃🍃 学报君想和大家分享三道关于种树的数学题,随着种树限制条件的增多、树林规模扩大,题目难度从小学数学到高数逐渐递增。
植树节快乐|用小学数学到高数的知识思考种树,你能种到哪一步?
小学课本的“七桥问题”
柯尼斯堡七桥问题(Seven Bridges of Konigsberg)是图论中的著名问题,也是世界上第一个图论问题,这个问题是基于一个现实生活中的事例:当时东普鲁士柯尼斯堡(今日俄罗斯加里宁格勒)市区跨普列戈利亚河两岸,河中心有两个小岛。
1229 0
高中的回忆
在十几年的求学历程中,高中和大学似乎是离我们最近的回忆了,今天和高中同学在一起吃饭聊天,无意中听他说了句,高中毕业已经十几年了,想想虽然还不是昨天那么临近,但是感觉也就近几年的光阴发生的事情。
1038 0