zoukankan      html  css  js  c++  java
  • 【IOI2000】邮局设置问题

    现在连基础DP都要看题解和代码才能写出来了,怎么办嘛QAQ

    原题:

    一些村庄建在一条笔直的高速公路边上,我们用一条坐标轴来描述这条公路,每个村庄的坐标都是整数,没有两个村庄的坐标相同。两个村庄的距离定义为坐标之差的绝对值。我们需要在某些村庄建立邮局。使每个村庄使用与它距离最近的邮局,建立邮局的原则是:所有村庄到各自使用的邮局的距离总和最小。
    数据规模:1<=村庄数<=300,  1<=邮局数<=30,  1<=村庄坐标<=10000

    用dis表示若使在i-j中选某点建站,这个点到i-j中每个点距离和的最小值

    贪心:选i-j的中点是建站是最优的,可以使用显然法证明(逃

    f[i][j]表示一直到第i个点,建了j站的最优质

    把j的循坏放外面,也就是先枚举建站的数量,状态转移方程为f[k][j-1]+dis[k+1][i] , j-1<=k<i

    意思是枚举把站建在j-1到i的情况

    感觉NOIP要挂了,怎么办嘛QAQ

    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 using namespace std;
     7 int n,m,a[110000];
     8 int f[310][310],dis[310][310];
     9 int main(){//freopen("ddd.in","r",stdin);
    10     memset(f,10,sizeof(f));
    11     cin>>n>>m;
    12     for(int i=1;i<=n;i++)  scanf("%d",&a[i]);
    13     for(int i=1;i<=n;i++)
    14         for(int j=i+1;j<=n;j++)
    15             dis[i][j]=dis[i][j-1]+a[j]-a[(i+j)>>1];//贪心,若使一段去间到区间内某点距离和最小,则某点取中点
    16     for(int i=1;i<=n;i++){
    17         f[i][i]=0;
    18         f[i][1]=dis[1][i];
    19     }
    20     for(int j=2;j<=m;j++)
    21         for(int i=j+1;i<=n;i++)
    22             for(int k=j-1;k<i;k++)
    23                 f[i][j]=min(f[i][j],f[k][j-1]+dis[k+1][i]);
    24     cout<<f[n][m]<<endl;
    25     return 0;
    26 }
    View Code
  • 相关阅读:
    【笔记】常见的架构风格
    【笔记】机器学习的数学基础
    【入门】机器学习基础理论
    【产品】海康威视工业相机
    开源搜索引擎与框架
    xmodmap系列工具,用于键盘设置
    【转载】Linux中功能强大的截图工具: Flameshot
    Ubuntu系统环境及配置
    【入门】CloudCompare使用教程
    Linux安装NVIDIA显卡驱动
  • 原文地址:https://www.cnblogs.com/JSL2018/p/5953747.html
Copyright © 2011-2022 走看看