OpenJudge 7624 山区建小学
在openjudge似乎无法凭题号搜到题...?
- 总时间限制:
- 1000ms
- 内存限制:
- 65536kB
- 描述
-
政府在某山区修建了一条道路,恰好穿越总共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
“明确告诉你是动规题,还不会做吗?”
“还是不会”
思路一开始就有了,但是实现起来还怪麻烦的
根据题意,我们可以把这些村庄间的道路连成了一条长链。想象一下这条链从左到右延伸,上面的某些结点已经建了学校,我们在这些结点的右侧找一个结点a,建一个新的学校。
新学校管辖的结点范围有多大呢?
结点a右边的村庄全部应该受a学校管辖(想一想,为什么),结点左边的学校则需要枚举判断了。
在决策结点a的学校之前,我们应该已经决策了另外一些已建好的学校,它们的决策方式和上面是相同的。
假设我们已经决策过i-1个村庄是否建了学校,正在决策第i个,之前建好的学校管辖范围是1~k,那么新学校的管辖范围应该是k+1~m,(k的范围是"已有学校数"~m-1)
设f[决策的村庄数][建的小学数]=题目要求的距离,s[管辖区起点][管辖区终点]=这片辖区内建一个学校,区内村庄到学校的距离和。
f[i][j]=min(f[i][j],f[k][j-1]+s[k+1][i])
下面上代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const int inf=99999999;
int f[510][510];
int dis[510][510];//从i到j距离
int d[510];
int s[510][510];
//s[管辖区起点][管辖区终点]=这片辖区内建一个学校,区内村庄到学校的距离和
int n,m;
int dist(int i,int j){int x=0;int mid=(i+j)/2;for(int k=i;k<=j;k++)x+=dis[k][mid];return x;
}int main(){scanf("%d%d",&m,&n);int i,j,x;for(i=2;i<=m;i++){//从2开始,方便求各村庄间距离scanf("%d",&x);d[i]=d[i-1]+x;}//for(i=1;i<=m;i++)for(j=1;j<=m;j++){if(i==j)dis[i][j]=0;else dis[i][j]=dis[j][i]=abs(d[j]-d[i]);}//初始化两两距离 //for(i=1;i<=m;i++)for(j=1;j<=m;j++)s[i][j]=dist(i,j);//计算一个管辖从i到j村庄的学校到这些村庄的距离和//for(i=1;i<=m;i++)for(j=1;j<=m;j++)f[i][j]=inf;for(i=1;i<=m;i++)f[i][i]=0;for(i=1;i<=m;i++)f[i][1]=s[1][i];//只建一个学校的情况 //f初始化 /* //testfor(i=1;i<=m;i++)for(j=1;j<=m;j++)printf("%d ",s[i][j]);
*/ for(i=2;i<=m;i++){//村庄for(j=2;j<=min(i,n);j++){//学校 for(int k=j-1;k<=i-1;k++){//枚举已有的学校管辖的范围 if(i!=j)f[i][j]=min(f[i][j],f[k][j-1]+s[k+1][i]);} } }printf("%d",f[m][n]);}
OpenJudge 7624 山区建小学相关推荐
- 【Open Judge】7624 山区建小学
** 7624:山区建小学 ** ** 描述 ** 政府在某山区修建了一条道路,恰好穿越总共m个村庄的每个村庄一次,没有回路或交叉,任意两个村庄只能通过这条路来往.已知任意两个相邻的村庄之间的距离为d ...
- 7624:山区建小学
题目链接 描述 政府在某山区修建了一条道路,恰好穿越总共m个村庄的每个村庄一次,没有回路或交叉,任意两个村庄只能通过这条路来往.已知任意两个相邻的村庄之间的距离为di(为正整数),其中,0 < ...
- 信息学奥赛一本通(1197:山区建小学)
1197:山区建小学 时间限制: 1000 ms 内存限制: 65536 KB 提交数: 3900 通过数: 2713 [题目描述] 政府在某山区修建了一条道路,恰好穿越总共m ...
- 【披着递推皮的动态规划】 山区建小学 题解
今天小编随意写了一道老师布置的题,这是一道看起来很普通的题,我却不明白它为什么放在递推中-- 废话不多说,直接看题. ▍1197:山区建小学 [题目描述] 政府在某山区修建了一条道路,恰好穿越总共m个 ...
- 1197 山区建小学
1197 山区建小学 读题20分钟,想题10分钟,看代码20分钟,理解代码20分钟,写代码10分钟,调代码40分钟-(逃 个人感觉是练的递推里面比较复杂的,应该是一道绿题吧,光递推式就很难找 设状态a ...
- 动态规划——openjudge7624山区建小学
题目: 描述 政府在某山区修建了一条道路,恰好穿越总共m个村庄的每个村庄一次,没有回路或交叉,任意两个村庄只能通过这条路来往.已知任意两个相邻的村庄之间的距离为di(为正整数),其中,0 < i ...
- 【OpenJudge - noi - 7624】山区建小学(dp)
题干: 总时间限制: 1000ms 内存限制: 65536kB 描述 政府在某山区修建了一条道路,恰好穿越总共m个村庄的每个村庄一次,没有回路或交叉,任意两个村庄只能通过这条路来往.已知任意两个相邻的 ...
- 山区建小学(信息学奥赛一本通-T1197)
[题目描述] 政府在某山区修建了一条道路,恰好穿越总共m个村庄的每个村庄一次,没有回路或交叉,任意两个村庄只能通过这条路来往.已知任意两个相邻的村庄之间的距离为didi(为正整数),其中,0<i ...
- openjudge7624:山区建小学
描述 政府在某山区修建了一条道路,恰好穿越总共m个村庄的每个村庄一次,没有回路或交叉,任意两个村庄只能通过这条路来往.已知任意两个相邻的村庄之间的距离为di(为正整数),其中,0 < i < ...
最新文章
- 别在迷恋正则表达式解析html了,好吗?
- python编程案例教程书籍-Python程序设计案例教程
- .NET Core2.1下采用EFCore比较原生IOC、AspectCore、AutoFac之间的性能
- java 数据对_数据表与简单java类(一对多)
- Linux中常用的查找文件的命令
- linux安装phpredis扩展
- portal for arcgis 10.4的安装和配置及遇到的问题
- ORACLE DATAGURARD配置手记
- Redis 压缩列表原理与应用分析
- vue 前端显示图片加token_前端甩锅神器:vue中的mock使用
- PE知识复习之PE的各种头属性解析
- 百度Android在线语音识别SDK用法
- java连接mongo_java 连接mongodb
- 经典股票图形:蛟龙出海
- Linux命令iconv
- 【matlab图像处理】图像处理工具箱(1)
- 获取计算机特征码,如何查看计算机特征码
- 推荐歌曲《 起风了》
- 华为U5800刷机,Root权限
- PHP调用系统声卡,什么是声卡
热门文章
- python 代码库之遍历ttf字库编码和字符(含demo)
- (一)遗传算法基本概念总结
- 工作中需要MP4视频文件怎么办?用Python随手采集一些【订阅赠品】
- 计算机毕业设计SSM餐厅管理系统【附源码数据库】
- PostgreSQL 技术内幕(二) Greenplum-AO表
- 信息学奥赛一本通C++语言-----1120:同行列对角线的格
- fatal: The remote end hung up unexpectedly
- 中文文案排版风格指南
- 计算机的新兴技术在测绘工程领域的应用,测绘新技术在测绘工程测量中应用探讨.doc...
- ZYNQ学习笔记PS部分【基本介绍】