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. Neo4j图数据库从入门到精通(转)

    add by zhj: 转载时,目录没整理好,还会跳转到原文 其实RDB也可以存储多对多的关系,使用的是中间表,GDB使用的是边,RDB中的实体存储在数据表,而GDB存储在节点.两者使用的底层技术不同 ...

  2. Centos7利用rsync实现文件同步

    0x01 测试环境 CentOS 7.4 Rsync服务端:192.168.204.130 CentOS 7.4 Rsync客户端:192.168.204.168 0x02 rsync同步方式 第一种 ...

  3. TensorFlow的数据读取机制

    一.tensorflow读取机制图解 首先需要思考的一个问题是,什么是数据读取?以图像数据为例,读取的过程可以用下图来表示 假设我们的硬盘中有一个图片数据集0001.jpg,0002.jpg,0003 ...

  4. Java 线程的基本使用

    GitHub Page: http://blog.cloudli.top/posts/Java-线程的基本使用/ 创建线程 创建线程的方式有两种: 继承 Thread 类 实现 Runnable 接口 ...

  5. ELK学习笔记之ElasticSearch的集群(Cluster),节点(Node),分片(Shard),Indices(索引),replicas(备份)之间关系

    [Cluster]集群,一个ES集群由一个或多个节点(Node)组成,每个集群都有一个cluster name作为标识----------------------------------------- ...

  6. mysql删除重复数据(通过多个字段分组,删除某一字段为空的数据)

    DELETE FROM t_questions WHERE Id in ( SELECT Id FROM ( SELECT Id FROM `t_questions` WHERE (Name,Ques ...

  7. laravel在使用Composer安装插件时要求输入授权用户名密码解决办法

    在使用laravel-china源时需要输入密码,坑,换源, 先换腾讯的不行,最后试一下阿里云的可以: composer config -g repo.packagist composer https ...

  8. PIE截图方法的优化

    因为我们组的项目要通过截图获取数据,所以要经常使用截图工具,之前截图都是根据教程(https://www.cnblogs.com/PIESat/p/10243308.html)用的地图显示范围截图,而 ...

  9. Linux yum的配置 , python环境管理, nginx搭建简单学习

    Linux yum的配置 , python环境管理, nginx搭建简单学习 一丶配置yum的数据仓库 ### yum 工具, 方便,自行解决软件之间的依赖关系. # 配置yum源仓库 (可以使用,清 ...

  10. UUID生成库libuuid和crossguid

    libuuid是一个开源的用于生成UUID(Universally Unique Identifier,通用唯一标识符)的库. 可从https://sourceforge.net/projects/l ...