zoukankan      html  css  js  c++  java
  • 山区建小学(OJ 7624)

    描述

    政府在某山区修建了一条道路,恰好穿越总共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

    仍在Xing学长的帮助下完成了该题-QWQ

    解析:

    本题关键在于起始的预处理,将各个村庄的位置像数轴一样表示在pos数组里

    再开一个arr[ i ][ j ] 表示 i~j 村庄必要走的路线长度(可以看成i~j村庄到 1 个小学的最短路程总和)

    那么DP就容易啦

     

    代码 ^-^:

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    int arr[1001][1001],pos[1001],f[1001][1001];
    
    int main()
    {
        int n,k;
        scanf("%d%d",&n,&k);
        for(int i=2;i<=n;++i) {
            scanf("%d",&pos[i]);
            pos[i]+=pos[i-1];
        }
        for(int i=1;i<n;++i)
        {
            for(int j=i+1;j<=n;++j)    {
                arr[i][j]=arr[i][j-1]+pos[j]-pos[(i+j)>>1];
            }
        }
        memset(f,13,sizeof(f));
        for(int i=1;i<=n;++i)
            f[i][1]=arr[1][i];
            
        for(int i=2;i<=n;++i)
            for(int j=2;j<=k&&j<=i;++j)
                for(int q=j-1;q<i;++q){
                    f[i][j]=min(f[i][j],f[q][j-1]+arr[q+1][i]);
                }
        printf("%d",f[n][k]);
        return 0;        
    }

    updated:2018-10-24

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    int arr[1001][1001],pos[1001],f[1001][1001];
    
    int main()
    {
        int n,k;
        scanf("%d%d",&n,&k);
        for(int i=2;i<=n;++i) {
            scanf("%d",&pos[i]);
            pos[i]+=pos[i-1];
        }
        for(int i=1;i<n;++i)
        {
            for(int j=i+1;j<=n;++j) {
                arr[i][j]=arr[i][j-1]+pos[j]-pos[(i+j)>>1];
            }
        }
        memset(f,13,sizeof(f));
        for(int i=1;i<=n;++i)
            f[i][1]=arr[1][i]; //前 i 个村庄建 1 所小学 
            
        for(int i=2;i<=n;++i) //前 i 个村庄 
            for(int j=2;j<=k&&j<=i;++j) //建 j 所小学 
                for(int q=j-1;q<i;++q) { //前 q 个村庄分配 j-1 所小学 
                    f[i][j]=min(f[i][j],f[q][j-1]+arr[q+1][i]);
                }
        printf("%d",f[n][k]);
        return 0;        
    }
    从0到1很难,但从1到100很容易
  • 相关阅读:
    mac 10.15.7 修改PATH
    oc 属性类型一般用法
    ubuntu解压zip文件名乱码
    telnet 退出
    docker 根据容器创建镜像
    mac android adb device 没有显示设备
    Yii2 查看所有的别名 alias
    Yii2 App Advanced 添加 .gitignore
    ubuntu 18.04 搜狗突然就提示乱码
    An error occured while deploying the file. This probably means that the app contains ARM native code and your Genymotion device cannot run ARM instructions. You should either build your native code to
  • 原文地址:https://www.cnblogs.com/qseer/p/9436428.html
Copyright © 2011-2022 走看看