1473. [Ioi2000]Post加强版 n log^2 n做法

题面

有n个城市从负方向向正方向按照1至n标号,\(d[i]\)表示城市i离原点的距离并且\(d[1] = 0\),对于\(i \ne j\)有\(d[i] \ne d[j]\)。城市\(i\)里的居民人数为\(w[i]\),如果每个居民的信件需要投放到\(dis\)以外的邮局去,那么政府为了该城市的居民投放信件将总花费\(w[i] * dis\)的资金。另外,在城市\(i\)建立邮局的费用为\(c[i]\)。 找出一种方案,使得总花费最小。

是一道好题,但是如果只写\(n^2\)就是一道裸题了

\(subtask1 : n \leq 1000\)


int n; ll c[N],w[N],d[N],ds[N],s[N];
ll dp[N]; int main() {
n=rd();
rep(i,1,n) d[i]=rd();
rep(i,1,n) c[i]=rd();
rep(i,1,n) w[i]=rd();
d[0]=-1e9;
d[n+1]=1e9;
rep(i,1,n+1) {
ds[i]=ds[i-1]+d[i]*w[i];
s[i]=s[i-1]+w[i];
}
int pre=0;
rep(i,1,n+1) {
dp[i]=1e15;
int mid=i;
drep(j,i-1,pre) {
while(mid>=j && d[i]-d[mid] <= d[mid]-d[j]) mid--;
ll t=dp[j];
t+=d[i]*(s[i]-s[mid])-(ds[i]-ds[mid]);
t+=ds[mid]-ds[j]-(s[mid]-s[j])*d[j];
if(t<dp[i]) dp[i]=t,pre=j;
}
dp[i]+=c[i];
}
printf("%lld\n",dp[n+1]);
}

拓展!!!

\(subtask2 : n \leq 10^5\)

决策单调性求解

单调性比较明显:对于每一个\(i\),决策点为\(j\),那么有随着\(i\)的递增,\(j\)也递增

但是受于转移顺序的限制,我们无法直接套用分治单调性求解

那么如何做呢?

我们再套一层分治!

第一层分治,我们考虑\([l,mid]\)中的dp值对于\([mid+1,r]\)中\(dp\)值的贡献

第二层分治,用于完成上述问题

注意一下调用顺序

#include<cstdio>
#include<cctype>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std; #define reg register
typedef long long ll;
#define rep(i,a,b) for(reg int i=a,i##end=b;i<=i##end;++i)
#define drep(i,a,b) for(reg int i=a,i##end=b;i>=i##end;--i) char IO;
int rd(){
int s=0,f=0;
while(!isdigit(IO=getchar())) if(IO=='-') f=1;
do s=(s<<1)+(s<<3)+(IO^'0');
while(isdigit(IO=getchar()));
return f?-s:s;
} const int N=3e5+10; int n; ll c[N],w[N],d[N],ds[N],s[N];
ll dp[N];
int pos[N]; void Solve2(int l,int r,int L,int R) {
if(l>r) return;
int mid=(l+r)>>1;
ll mi=1e18,id=-1;
rep(i,L,R) {
int p=pos[(d[i]+d[mid])/2];
ll t=dp[i]+c[mid]+(ds[p]-ds[i])-d[i]*(s[p]-s[i])+d[mid]*(s[mid]-s[p])-(ds[mid]-ds[p]);
if(mi>t) mi=t,id=i;
}
dp[mid]=min(dp[mid],mi);
if(id==-1) return;
Solve2(l,mid-1,L,id);
Solve2(mid+1,r,id,R);
} void Solve1(int l,int r) {
if(l==r) return;
int mid=(l+r)>>1;
Solve1(l,mid);
Solve2(mid+1,r,l,mid+1);
Solve1(mid+1,r);
} int main() {
n=rd();
rep(i,1,n) d[i]=rd();
rep(i,1,n) c[i]=rd();
int p=1;
rep(i,0,3e5) if(d[p]==i) pos[i]=p,p++;
else pos[i]=pos[i-1];
rep(i,1,n) w[i]=rd();
rep(i,1,n) {
ds[i]=ds[i-1]+d[i]*w[i];
s[i]=s[i-1]+w[i];
}
rep(i,1,n) dp[i]=d[i]*s[i]-ds[i]+c[i];
Solve1(1,n);
ll ans=1e18;
rep(i,1,n) ans=min(ans,dp[i]+(ds[n]-ds[i])-d[i]*(s[n]-s[i]));
printf("%lld\n",ans);
}

1473. [Ioi2000]Post加强版 n log^2 n做法的更多相关文章

  1. Android安全–加强版Smali Log注入

    有的时候我们需要注入smali调用Log输出,打印字符串的值. 比如说: 如果我们要打印下面v1的值. new-instance v1, Ljava/lang/String; const-string ...

  2. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  3. POJ 2533 Longest Ordered Subsequence LCS O(n*log(n))

    题目链接 最长上升子序列O(n*log(n))的做法,只能用于求长度不能求序列. #include <iostream> #define SIZE 1001 using namespace ...

  4. 解读Android LOG机制的实现【转】

    转自:http://www.cnblogs.com/hoys/archive/2011/09/30/2196199.html http://armboard.taobao.com/ Android提供 ...

  5. POJ 2533 Longest Ordered Subsequence LIS O(n*log(n))

    题目链接 最长上升子序列O(n*log(n))的做法,只能用于求长度不能求序列. #include <iostream> #include <algorithm> using ...

  6. 决策单调性&wqs二分

    其实是一个还算 trivial 的知识点吧--早在 2019 年我就接触过了,然鹅当时由于没认真学并没有把自己学懂,故今复学之( 1. 决策单调性 引入:在求解 DP 问题的过程中我们常常遇到这样的问 ...

  7. 2018HN省队集训

    HNOI2018省队集训 Day 1 流水账 T1 tree 换根+求\(lca\)+求子树和,一脸bzoj3083遥远的国度的既视感.子树和讨论一下就好了,\(lca\)?也是大力讨论一波. 先写了 ...

  8. 2017FJ省队集训 游记

    2017FJ省队集训 游记 又是一篇流水账 Day 1 今天是省队集训的第一天.早上骑车去八中,到的时候汗流太多浑身湿透被杨哥哥和runzhe2000 d了,一个说我去游泳了一个说我打球了...流完汗 ...

  9. NOIP2016考前做题(口胡)记录

    NOIP以前可能会持续更新 写在前面 NOIP好像马上就要到了,感觉在校内训练里面经常被虐有一种要滚粗的感觉(雾.不管是普及组还是提高组,我都参加了好几年了,结果一个省一都没有,今年如果还没有的话感觉 ...

随机推荐

  1. lombok的介绍、使用、简单分析和插件

    学习下Lombok. 关于POJO Java面向对象编程中的特性中有封闭性和安全性.封闭性即对类中的域变量进行封闭操作,即用private来修饰他们.如此一来,其他类就不能对该变量访问了.这样,我们就 ...

  2. 解决SpringBoot无法读取js/css静态资源的新方法

    前言 作为依赖使用的SpringBoot工程很容易出现自身静态资源被主工程忽略的情况.但是作为依赖而存在的Controller方法却不会失效,我们知道,Spring MVC对于静态资源的处理也不外乎是 ...

  3. java8 Lambda 表达式和函数式接口快速理解

    前言 接上篇文章 java8 新特性 由于上篇过于庞大,使得重点不够清晰,本篇单独拿出 java8 的 Lambda 表达式和函数式接口说明. Lambda 表达式 lambda 表达式其实就是使用了 ...

  4. SpringBoot 打包成war

    1.修改pom.xml文件 <packaging>war</packaging> <properties> <project.build.sourceEnco ...

  5. C# vb .NET读取识别条形码线性条码UPC-E

    UPC-E是比较常见的条形码编码规则类型的一种.如何在C#,vb等.NET平台语言里实现快速准确读取该类型条形码呢?答案是使用SharpBarcode! SharpBarcode是C#快速高效.准确的 ...

  6. 记一次CSS反爬

    目标网址:猫眼电影 主要流程 爬取每一个电影所对应的url 爬取具体电影所对应的源码 解析源码,并下载所对应的字体 使用 fontTools 绘制所对应的数字 运用机器学习的方法识别对应的数字 在源码 ...

  7. 基于vue+springboot+docker网站搭建【六】安装中间件

    安装中间件 去另外一台2核4G的机器先安装docker,然后安装后台项目使用的中间件 一.mysql 下载镜像:docker pull mysql:5.7 启动镜像实例:docker run -p 3 ...

  8. vim 如何复制文件中多行到另一个文件

    1.打开文件 vim a.txt b.tx 或者 vim *.txt 2.文件间切换 :n 切换到下一个文件 :wn 保存再切换 :N 到上一个文件 :wN 保存再切换 :.= 看当前行 3.假定当前 ...

  9. ES6-面向对象

    1.老版的面向对象: function User(name,pass){ this.name=name; this.pass=pass; } User.prototype.showName=funct ...

  10. Python数据分析工具:Pandas之Series

    Python数据分析工具:Pandas之Series Pandas概述Pandas是Python的一个数据分析包,该工具为解决数据分析任务而创建.Pandas纳入大量库和标准数据模型,提供高效的操作数 ...