【noi 2.6_7624】山区建小学(DP)
2024-10-16 22:22:34
题意:在m个村庄建n个小学,求所有村到最近小学的距离总的最小值。
解法:由于题目是求“离最近的学校”,而不是前一个学校,所以枚举学校的具体位置不方便,可转化成区间(学校居区间中间)的划分问题。
实现:dis[l][r]存村庄l和村庄r之间建1个小学的最小距离和,即到中间那个村庄的距离和。f[i][j]表示前i个村庄建了j个小学的最小距离和。
1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4
5 const int N=510,M=510;
6 int a[N],s[N],f[N][M],dis[N][N];
7
8 int mmin(int x,int y) {return x<y?x:y;}
9 int main()
10 {
11 int n,m;
12 scanf("%d%d",&n,&m);
13 s[1]=0;
14 for (int i=2;i<=n;i++)
15 {
16 scanf("%d",&a[i]);
17 s[i]=s[i-1]+a[i];//=1到i的距离
18 }
19 for (int l=1;l<=n;l++)
20 for (int r=l;r<=n;r++)
21 {
22 int mid=(l+r)>>1;
23 dis[l][r]=0;
24 for (int k=l;k<mid;k++)
25 dis[l][r]+=s[mid]-s[k];
26 for (int k=mid+1;k<=r;k++)
27 dis[l][r]+=s[k]-s[mid];
28 }
29 memset(f,63,sizeof(f));
30 f[0][0]=0;
31 for (int i=1;i<=n;i++)
32 for (int j=1;j<=m;j++)
33 {
34 if (j>i) {f[i][j]=0;continue;}
35 for (int k=j-1;k<i;k++)
36 f[i][j]=mmin(f[i][j],f[k][j-1]+dis[k+1][i]);
37 }
38 printf("%d\n",f[n][m]);
39 return 0;
40 }
最新文章
- openlayer3 获取feature
- shutdown的简单小应用
- 仿W8屏保
- AWK改变输入输出分隔符实例分析
- ASP.NET MVC使用jQuery无刷新上传
- Mongoose 是什么?
- Docker实例教程[超详细](一)
- Helpers\RainCaptcha
- dedecms网站如何做在线订单功能
- Unity3D 相机跟随主角移动
- ocean所用的蝴蝶纹理
- java代码实现ftp服务器的文件上传和下载
- Spring之对象依赖关系(依赖注入Dependency Injection)
- iOS - 抖音效果
- vSphere虚拟化管理平台的功能
- git 生成秘钥
- xml json
- 关于STM32 SPI NSS的讨论
- [jquery-ajax] jquery ajax 三种情况对比
- 使用STL sort对字符串按字典序排序