zoukankan      html  css  js  c++  java
  • Post Office

    Post Office poj-1160

        题目大意:给你在数轴上的n个村庄,建立m个邮局,使得每一个村庄距离它最近的邮局的距离和最小,求距离最小和。

        注释:n<=300,m<=min(n,30)

          想法:一道DP题,超级有趣。变强中的我查了题解。是这样的:我们定义两个数组,分别是dp和sum。

            dp[i][j]表示从第一个村庄到第i个村庄建立j个邮局的最小和。

            sum[i][j]表示从第i个村庄到第j个村庄建立一个邮局的最小代价。

          然后,我们发现sum数组是可以预处理出来的。对于sum[i][j]来说,建立的邮局一定是i和j中间的那一个地方。可能是一个村庄,也可能是两个村庄之间。如果是两个村庄之间,显然对于sum[i][j]来说是没有影响的,但是对于sum[i][j+1]来说越靠近j+1越小,这是一定的,所以,我们可以非常简单的总结出sum[i][j]=sum[i][j-1]+pos[i]-pos[(i+j)/2]。这样,我们预处理出了sum数组,最重要的,我们期望处理dp数组。有了sum数组,我们对于dp[i][j]来讲可以枚举断点k,使得k+1到j只建立一个邮局,这样,我们就处理出了dp数组。

        最后,附上丑陋的代码... ...

     1 #include <iostream>
     2 #include <cstdio>
     3 #define N 310
     4 using namespace std;
     5 int sum[N][N],dp[N][N],pos[N];
     6 int main()
     7 {
     8     int n,m;
     9     while(~scanf("%d%d",&n,&m))
    10     {
    11         memset(sum,0,sizeof(sum));
    12         for(int i=1;i<=n;i++)
    13         {
    14             scanf("%d",&pos[i]);
    15         }
    16         for(int i=1;i<=n;i++)
    17         {
    18             for(int j=i+1;j<=n;j++)
    19             {
    20                 sum[i][j]=sum[i][j-1]+pos[j]-pos[(i+j)/2];
    21             }
    22         }
    23         memset(dp,0x3f,sizeof(dp));
    24         for(int i=1;i<=n;i++)
    25         {
    26             dp[i][1]=sum[1][i];
    27         }
    28         for(int j=2;j<=m;j++)//如果j=1的话是sum的事情,和dp数组无关 
    29         {
    30             for(int i=j+1;i<=n;i++)//枚举dp的左端点 
    31             {
    32                 for(int k=j-1;k<i;k++)//枚举断点 显然断点是有范围的 
    33                 {
    34                        dp[i][j]=min(dp[i][j],dp[k][j-1]+sum[k+1][i]);
    35                 }
    36             }
    37         }
    38         printf("%d
    ",dp[n][m]);
    39     }
    40     return 0;
    41 }

        小结:类似于RMQ的思想,我们必须将小范围的枚举在外面,因为之后会用到。在这里,我倒是有一个想法,就是卡内存。因为我们发现,我所用到的dp数组只有刚刚更新过的和正在更新的,所以,我们可以将dp数组的内存除以(n/2),这显然是极好的... ...

  • 相关阅读:
    安装IIS
    SQL 通过某个字段名称找到数据库中对应的表
    javascript 操作 drop down list
    The project type is not supported by this installationVS2005
    Get 和 Post 简介
    .Net 控件调用 javascript事件
    JQuery检测浏览器版本
    开车要点
    linux shell工程师要求
    memory management
  • 原文地址:https://www.cnblogs.com/ShuraK/p/8372614.html
Copyright © 2011-2022 走看看