首页 > 代码库 > 【noi 2.6_7624】山区建小学(DP)

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

题意:在m个村庄建n个小学,求所有村到最近小学的距离总的最小值。

解法:由于题目是求“离最近的学校”,而不是前一个学校,所以枚举学校的具体位置不方便,可转化成区间(学校居区间中间)的划分问题。

 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 }

 

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