• b_lg_邮局(暴力dp / 预处理优化 / 四边形不等式)


    为了建立邮局,应选择他们建造的位置,使每个村庄与其最近的邮局之间的距离总和最小。
    你要编写一个程序,已知村庄的位置和邮局的数量,计算每个村庄和最近的邮局之间所有距离的最小可能的总和。
    输出格式
    第一行包含一个整数S,它是每个村庄与其最近的邮局之间的所有距离的总和。

    方法一:dp

    蒙的:一个邮局放在中间位置得到的距离总和最小;

    • 定义状态
      • f[i][j] 表示在前i个村庄中建j个邮局的最小距离总和
    • 思考初始化:
      • f[...][...]=+inf, f[0][0]=0
    • 思考状态转移方程
      • f[i][j]=min(f[i][j], f[k][j-1]+dist(k+1, i)),看是更优:前i个村庄中建j个邮局的最小距离 | 在前k个村庄中建j-1个以及第j个邮局在k+1到i这些村庄中建立的距离
    • 思考输出:f[V][P]

    \(O(v^3 × p)\)tle之40/100...

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int V=3005, P=305, inf=0x3f3f3f3f;
    int v,p,f[V][P],A[V];
    
    int dist(int l, int r) {
        int m=l+(r-l)/2, ans=0;
        for (int i=l; i<m; i++) ans+=A[m]-A[i];
        for (int i=m+1; i<=r; i++) ans+=A[i]-A[m];
        return ans;
    }
    int main() {
        std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
        cin>>v>>p;
        for (int i=1; i<=v; i++) cin>>A[i];
        memset(f, inf, sizeof f);
        f[0][0]=0;
    
        for (int j=1; j<=p; j++)    //邮局
        for (int i=1; i<=v; i++)    //村庄
        for (int k=0; k<i; k++) {   //少量村庄
            f[i][j]=min(f[i][j], f[k][j-1]+dist(k+1, i));
        }   
        cout << f[v][p];
        return 0;
    }
    

    预处理每个村庄中心到其它点的距离到dist[i][j]中去代替函数dist(),枯了还是40/100...

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int V=3005, P=305, inf=0x3f3f3f3f;
    int v,p,f[V][P],A[V],dist[V][V];
    
    int initdist() {
        for (int i=1; i<v; i++)
        for (int j=i+1; j<=v; j++) {
            dist[i][j]=dist[i][j-1]+A[j]-A[i+j>>1];
        }
    }
    
    int main() {
        std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
        cin>>v>>p;
        for (int i=1; i<=v; i++) cin>>A[i];
        memset(f, inf, sizeof f); f[0][0]=0;
        initdist();
    
        for (int j=1; j<=p; j++)    //邮局
        for (int i=1; i<=v; i++)    //村庄
        for (int k=0; k<i; k++) {   //少量村庄
            f[i][j]=min(f[i][j], f[k][j-1]+dist[k+1][i]);
        }   
        cout << f[v][p];
        return 0;
    }
    

    复杂度分析

    • Time\(O(v^2×p)\)
    • Space\(O(vp)\)
  • 相关阅读:
    Redis进阶实践之一VMWare Pro虚拟机安装和Linux系统的安装
    HTTP常见面试题
    HBase WAL原理学习
    HBase TableExistsException: hbase:namespace
    HBase常用操作之namespace
    Hbase原理、基本概念、基本架构
    hbase 修复 hbase hbck
    hbase数据备份或者容灾方案
    Hbase 日常运维
    HBase shell scan 模糊查询
  • 原文地址:https://www.cnblogs.com/wdt1/p/13673842.html
Copyright © 2020-2023  润新知