zoukankan      html  css  js  c++  java
  • BZOJ2933: [Poi1999]地图

    Description

     
    一个人口统计办公室要绘制一张地图。由于技术的原因只能使用少量的颜色。两个有相同或相近人口的区域在地图应用相同的颜色。例如一种颜色k,则A(k) 是相应的数,则有:
    • 在用颜色k的区域中至少有一半的区域的人口不大于A(k)
    • 在用颜色k的区域中至少有一半的区域的人口不小于A(k)
    区域颜色误差是该区域的人口与A(k)差的绝对值。累计误差是所有区域颜色误差的总和。我们要求出一种最佳的染色方案(累计误差最小)。
    任务
    写一个程序:
    • 读入每个区域的人口数
    • 计算最小的累计误差
    • 将结果输出

    Input

     
    第一行有一个整数n,表示区域数,10< n <3000。在第二行中的数m表示颜色数,2 <= m <= 10。在接下来的n中每行有一个非负整数,表示一个区域的人口。人口都不超过2^30

    Output

    输出一个整数,表示最小的累计误差

    Sample Input

    11
    3
    21
    14
    6
    18
    10
    2
    15
    12
    3
    2
    2

    Sample Output

    15
    题解:首先我们很容易想到,要使误差小,先将所有的省区排序,再来考虑将这些省区分段,一段算作一个颜色。
    然后设f[i][j]为前i个省区用j个颜色的最小误差,W[i][j]设为i~j省区为同个颜色会带来的误差,先通过前缀和把w数组处理好,然后用一个变量k来松弛i~j这个区间,若k+1~i为同个颜色 ,则f[i][j]=min(f[i]][j],f[k][j-1]+w[k+1][i]]);
    不过前缀和的地方要稍微推一下。
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int n,m,mid,a[3005],w[3005][3005],f[3005][20];
    long long s[3005],k1,k2;
    int min(int a,int b)
    {
        if (a>b) return b;
        else return a;
    }
    int main()
    {
      cin>>n>>m;
      for (int i=1;i<=n;i++) cin>>a[i];
      sort(a+1,a+n+1);
      s[0]=0;
      for (int i=1;i<=n;i++) s[i]+=s[i-1]+a[i];
      for (int i=1;i<=n;i++)
      for (int j=i;j<=n;j++)
      {
        mid=(i+j+1)/2;
        k1=a[mid]*(mid-i)-(s[mid-1]-s[i-1])+(s[j]-s[mid])-a[mid]*(j-mid);//把这段区间涂成一个颜色所会带来的误差值
        w[i][j]=k1;
      }
      for (int i=0;i<=n+1;i++)
      for (int j=0;j<=m+1;j++)
      f[i][j]=1073741825;
      f[0][0]=0;
      for (int i=1;i<=n;i++)
      for (int j=1;j<=m;j++)
      for (int k=0;k<=i-1;k++)
      f[i][j]=min(f[i][j],f[k][j-1]+w[k+1][i]);//把它分成两段,k+1~i用一个颜色
      cout<<f[n][m]<<endl;
      return 0;
    }
  • 相关阅读:
    【转载】褪去华衣 裸视学习 探讨系列
    最简单的视频网站(JavaEE+FFmpeg)
    过段时间要换博客了
    计网3
    计网1
    物理层计算题
    计网4
    子网划分与CIDR
    百度=残留在墙后的垃圾
    计网2
  • 原文地址:https://www.cnblogs.com/2014nhc/p/6236578.html
Copyright © 2011-2022 走看看