【noi 2.6_7624】山区建小学(DP)

题意:在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 }

 

转载于:https://www.cnblogs.com/konjak/p/5896063.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值