没有记性。到DP不得不写博了,三天后又忘的干干净净。DP是啥 :-)

一道久到不能再久的题了。

OpenJudge  7624:山区建小学

总时间限制: 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为中心向两边扩散下一个点所走的距离d=d(前一个点)+d(当前);期望重复次数越多路段d越小。然后,就有dalao证明了区间[i,j]中在中点处建学校路段和为最小(建1所学校);脑洞又开到:如果区间内点数为偶数,如何选择中点?手推数据发现其实都是一样的。在此计算的为距离和,所以实则计算的是 d总+=di*重复次数。如图:

考虑DP:从第一个村庄开始扩展,在区间[1,i],每加入一个点i进行决策 。

状态转移方程:f[i][j]=min(f[i][j],f[k][j-1]+w[k+1][i]);

f[i][j] 表示到第i个点建j所学校的最优;在区间[1.i]间枚举断点,断点前为在区间[1,k]建j-1所学校的最优,断点后为在区间[k+1,i]建1所学校的最优。

 #include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std; int n,m;
int d[][],f[][],w[][],s[]; int pre(int a,int b){
int x=;
int mid=(a+b)>>;
for(int i=a;i<=b;++i)
x+=d[i][mid];
return x;
} int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=n;++i){//s[i]---第i-1个村庄到第i个村庄间的距离
int x;
scanf("%d",&x);
s[i]=s[i-]+x;
}
memset(f,0x3f3f3f,sizeof(f));
for(int i=;i<=n;++i){
f[i][i]=;
for(int j=;j<=n;++j){
if(i==j)d[i][j]=;
d[i][j]=d[j][i]=abs(s[i]-s[j]);//(i,j)间的距离
}
}
for(int i=;i<=n;++i)//(i,j)建1所小学min
for(int j=i+;j<=n;++j)
w[i][j]=pre(i,j);
for(int i=;i<=n;++i)f[i][]=w[][i];
for(int i=;i<=n;++i)// 村庄
for(int j=;j<=min(i,m);++j)//j---学校 min(枚举的村庄数,学校数)
for(int k=j-;k<i;++k)//min( f[i][j],建j-1所学校所达范围(1,k)+新建第j所学校范围(k+1,i))
if(i!=j)f[i][j]=min(f[i][j],f[k][j-]+w[k+][i]); printf("%d",f[n][m]);
return ;
}

#DP# ----- OpenJudge山区建小学的更多相关文章

  1. 【OpenJudge7624】【区间DP】山区建小学

    山区建小学 总时间限制: 1000ms 内存限制: 65536kB [描述] 政府在某山区修建了一条道路,恰好穿越总共m个村庄的每个村庄一次,没有回路或交叉,任意两个村庄只能通过这条路来往.已知任意两 ...

  2. 山区建小学(区间DP)

    山区建小学 时间限制: 1 Sec  内存限制: 128 MB提交: 17  解决: 5[提交][状态][讨论版][命题人:quanxing] 题目描述 政府在某山区修建了一条道路,恰好穿越总共m个村 ...

  3. P4677 山区建小学|区间dp

    P4677 山区建小学 题目描述 政府在某山区修建了一条道路,恰好穿越总共nn个村庄的每个村庄一次,没有回路或交叉,任意两个村庄只能通过这条路来往.已知任意两个相邻的村庄之间的距离为di 为了提高山区 ...

  4. 7624:山区建小学(划分dp)

    7624:山区建小学 查看 提交 统计 提问 总时间限制: 1000ms 内存限制: 65536kB 描述 政府在某山区修建了一条道路,恰好穿越总共m个村庄的每个村庄一次,没有回路或交叉,任意两个村庄 ...

  5. NOI题库7624 山区建小学(162:Post Office / IOI2000 POST OFFICE [input] )

    7624:山区建小学 Description 政府在某山区修建了一条道路,恰好穿越总共m个村庄的每个村庄一次,没有回路或交叉,任意两个村庄只能通过这条路来往.已知任意两个相邻的村庄之间的距离为di(为 ...

  6. 山区建小学(区间dp+前缀和+预处理)

    [题目描述] 政府在某山区修建了一条道路,恰好穿越总共m个村庄的每个村庄一次,没有回路或交叉,任意两个村庄只能通过这条路来往.已知任意两个相邻的村庄之间的距离为di(为正整数),其中,0 < i ...

  7. OpenJudge 7624 山区建小学

    在openjudge似乎无法凭题号搜到题...? 总时间限制:  1000ms  内存限制:  65536kB 描述 政府在某山区修建了一条道路,恰好穿越总共m个村庄的每个村庄一次,没有回路或交叉,任 ...

  8. luogu P4677 山区建小学 |dp

    题目描述 政府在某山区修建了一条道路,恰好穿越总共nnn个村庄的每个村庄一次,没有回路或交叉,任意两个村庄只能通过这条路来往.已知任意两个相邻的村庄之间的距离为did_idi​(为正整数),其中,0& ...

  9. Openjudge — 7624 山区建小学

    问题描述 政府在某山区修建了一条道路,恰好穿越总共m个村庄的每个村庄一次,没有回路或交叉,任意两个村庄只能通过这条路来往.已知任意两个相邻的村庄之间的距离为di(为正整数),其中,0 < i & ...

随机推荐

  1. 004-Python字符串

    Python 字符串(str) 字符串是 Python 中最常用的数据类型.我们可以使用引号('或")来创建字符串.创建字符串很简单,只要为变量分配一个值即可. var1 = "H ...

  2. Maven项目中提示:Eclipse “cannot be resolved to a type” error

    我的解决办法是这个: 临时解决方法是:Clean项目 ********百度到的其他解决办法,统一归纳此处****************** (1)jdk不匹配(或不存在) 项目指定的jdk为“jdk ...

  3. linux下用script和scriptreplay对命令行操作录像

    以前查看自己的历史操作,都是history里来查看的,只有命令,有时候系统返回的什么也没有,看了script可以对自己的操作进行录像,于是自己也做个. 要记录操作之前输入命令: [root@wulao ...

  4. Android开发学习资源

    https://developer.android.google.cn/training/index.html

  5. 学习Redis从这里开始

    本文主要内容 Redis与其他软件的相同之处和不同之处 Redis的用法 使用Python示例代码与Redis进行简单的互动 使用Redis解决实际问题 Redis是一个远程内存数据库,它不仅性能强劲 ...

  6. Hibernate查询之API查询

    Hibernate在检索数据上,可以使用SQL.HQL和官方API进行查询,本人主要利用API进行相关查询的小demo. 话不多少直接上demo. demo1:基本查询 /** * 默认不加任何条件的 ...

  7. Android非常实用的开源项目框架

    我将文章中所描述的项目都集成在一个apk中,可以直接运行查看效果,2.2以上的机器都可以运行.因为不让直接上传apk文件,我压缩成了zip包 1. Universal-Image-Loader 实现异 ...

  8. Docker Swarm集群

    Docker Swarm集群 IP 10.6.17.11  管理节点 IP 10.6.17.12   节点A IP 10.6.17.13   节点B IP 10.6.17.14   节点C 安装 Sw ...

  9. Bar Chart of Frequency of modals in different sections of the Brown Corpus

    Natural Language Processing with Python Chapter 4.8 colors = 'rgbcmyk' # red, green, blue, cyan, mag ...

  10. Linux下Nginx、PHP、MySQL、Redis开机自启动设置

    一.Nginx开机启动设置 1.在/etc/init.d/目录下创建脚本 vi /etc/init.d/nginx 2.更改脚本权限 chmod 775 /etc/init.d/nginx 3.编写脚 ...