4951: [Wf2017]Money for Nothing 决策单调性 分治
Bzoj4951:决策单调性 分治
国际惯例题面:
一句话题面:
供应商出货日期为Ei,售价为Pi;用户收购截止日期为Si,收购价格为Gi。我们要求max((Si-Ej)*(Gi-Pj))。
显然如果我们把这两者都按照Ei,Si递增排序,则Pi,Gi都是单调降的。
为什么?如果一个供应商生产时间后且价格高,显然你不会选择他;如果一个用户购买时间短且收购价格低,显然你也不会选择他。
然后我们会写n^2暴力了。考虑优化。
这种DP要么斜率+数据结构优化,要么就是决策单调性。
考虑斜率优化,发现这是一个三维凸包问题,不会做。
考虑决策单调性,我们猜想,对于Si递增的用户,采用的最有供货商的Ei也是单调增的。
如何证明,考虑反证法。
我们假设两个供货商出货日期为E1,E2,价格为P1,P2。
两个用户截止日期为S1,S2,收购价格为G1,G2。
不妨令E1<E2,P1>P2且S1<S2,G1>G2。
如果不满足决策单调性,我们有:
(E1-S2)*(P1-G2)>(E1-S1)*(P1-G1)
(E2-S1)*(P2-G1)>(E2-S1)*(P2-G2)
整理得:
S2*G2-S1*G1>P1*(S2-S1)+E1*(G2-G1)
P2*(S2-S1)+E2*(G2-G1)>S2*G2-S1*G1
根据不等号的传递性,我们有:
P2*(S2-S1)+E2*(G2-G1)>P1*(S2-S1)+E1*(G2-G1)
整理得:
(E2-E1)*(G2-G1)>(S2-S1)*(P1-P2)
根据我们的前提条件,E2-E1>0,G2-G1<0,S2-S1>0,P1-P2>0。
这样的话,左式((E2-E1)*(G2-G1))<0,右式((S2-S1)*(P1-P2))>0。
显然一个<0的数大于一个>0的数是不可能的,所以假设不成立,原结论成立,决策单调性得证。
然后就是代码实现的问题了,我用的是经典的分治写法,就是对于每一个用户区间的中点,找到最优供货商,然后再分离区间递归计算。
注意如果乘法的时候两边都是负数,我们应该特判掉并返回-inf(因为这个状态不合法,不能更新答案),但是只有一边是负数的时候,我们应该计算出他的值(虽然这个状态不能更新答案,但是这个状态能更新决策)。
我一开始看到<0就返回-inf,WA了不知道多少发,身败名裂。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
typedef long long int lli;
const int maxn=5e5+1e2;
const lli inf=0x3f3f3f3f3f3f3f3fll; struct Point {
int x,y;
friend bool operator < (const Point &a,const Point &b) {
return a.x != b.x ? a.x < b.x : a.y < b.y;
}
}pro[maxn],usr[maxn]; inline int fix(Point* dst,int len,bool tpe) { // tpe = 0 solve provider by pushing stack , cmp = 1 solve user by poping stack .
static Point stk[maxn];
std::sort(dst+,dst++len);
int top = ;
if( !tpe ) {
for(int i=;i<=len;i++) if( !top || stk[top].y > dst[i].y ) stk[++top] = dst[i];
} else {
for(int i=;i<=len;i++) {
while( top && stk[top].y <= dst[i].y ) --top;
stk[++top] = dst[i];
}
}
memcpy(dst+,stk+,sizeof(Point)*top);
return top;
} lli ans; inline lli calc(const Point &pro,const Point &usr) {
if( usr.x < pro.x && usr.y < pro.y ) return -inf;
return (lli) ( usr.x - pro.x ) * ( usr.y - pro.y );
}
inline void solve(int pl,int pr,int ul,int ur) {
if( pl == pr || ul == ur ) {
for(int i=pl;i<=pr;i++) for(int j=ul;j<=ur;j++) ans = std::max( ans , calc(pro[i],usr[j]) );
return;
}
int pmid = pl , umid = ( ul + ur ) >> ;
lli cur = -inf, cal;
for(int i=pl;i<=pr;i++)
if( ( cal = calc(pro[i],usr[umid]) ) > cur ) cur = cal , pmid = i;
ans = std::max( ans , cur );
if( ul < umid ) solve(pl,pmid,ul,umid-);
if( umid < ur ) solve(pmid,pr,umid+,ur);
} int main() {
static int n,m;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) scanf("%d%d",&pro[i].x,&pro[i].y);
for(int i=;i<=m;i++) scanf("%d%d",&usr[i].x,&usr[i].y);
n = fix(pro,n,) , m = fix(usr,m,);
solve(,n,,m) , printf("%lld\n",ans);
return ;
}
作为业界良心的我还是附送官方数据吧(Lemon格式打包):
链接:https://pan.baidu.com/s/1jbjZ6OvS5Wf5Ls46nvrRNg 密码:434d
祈る事を諦めた
我已经放弃了向神祈祷
透き通る空の朝
在那透明澄澈的清晨中
どんな気持ち抱えてても
无论怀抱着怎样的心绪
誰にも届かないなんて
也完全无法向他人传递
まるで私はエコー
仿佛只是自身在不断回响
4951: [Wf2017]Money for Nothing 决策单调性 分治的更多相关文章
- P2877 [USACO07JAN]牛校Cow School(01分数规划+决策单调性分治)
P2877 [USACO07JAN]牛校Cow School 01分数规划是啥(转) 决策单调性分治,可以解决(不限于)一些你知道要用斜率优化却不会写的问题 怎么证明?可以暴力打表 我们用$ask(l ...
- [NAIPC2016]Jewel Thief(决策单调性+分治)
[NAIPC2016]Jewel Thief(决策单调性+分治) 题面 原题提交地址(题目编号H) 原题面下载地址 有\(n\)个物品,每个物品有一个体积\(w_i\)和价值\(v_i\),现在要求对 ...
- P3515 [POI2011]Lightning Conductor(决策单调性分治)
P3515 [POI2011]Lightning Conductor 式子可转化为:$p>=a_j-a_i+sqrt(i-j) (j<i)$ $j>i$的情况,把上式翻转即可得到 下 ...
- bzoj1897. tank 坦克游戏(决策单调性分治)
题目描述 有这样一款新的坦克游戏.在游戏中,你将操纵一辆坦克,在一个N×M的区域中完成一项任务.在此的区域中,将会有许多可攻击的目标,而你每摧毁这样的一个目标,就将获得与目标价值相等的分数.只有获得了 ...
- BZOJ 4951 [WF2017]Money for Nothing (决策单调优化DP+分治)
题目大意:略 题目传送门 不愧是$World final$的神题,代码短,思维强度大,细节多到吐..调了足足2h 贪心 我们利用贪心的思想,发现有一些工厂/公司是非常黑心的 以工厂为例,对于一个工厂$ ...
- [BZOJ5125]小Q的书架(决策单调性+分治DP+树状数组)
显然有决策单调性,但由于逆序对不容易计算,考虑分治DP. solve(k,x,y,l,r)表示当前需要选k段,待更新的位置为[l,r],这些位置的可能决策点区间为[x,y].暴力计算出(l+r)/2的 ...
- [loj6039]「雅礼集训 2017 Day5」珠宝 dp+决策单调性+分治
https://loj.ac/problem/6039 我们设dp[i][j]表示考虑所有价值小于等于i的物品,带了j块钱的最大吸引力. 对于ci相同的物品,我们一定是从大到小选k个物品,又发现最大的 ...
- bzoj4518: [Sdoi2016]征途(DP+决策单调性分治优化)
题目要求... 化简得... 显然m和sum^2是已知的,那么只要让sigma(si^2)最小,那就变成了求最小平方和的最小值,经典的决策单调性,用分治优化即可. 斜率优化忘得差不多就不写了 #inc ...
- 2019.02.21 bzoj2739: 最远点(决策单调性+分治)
传送门 题意简述:给一个N个点的凸多边形,求离每一个点最远的点. 思路:先根据初中数学知识证明决策是满足单调性的,然后上分治优化即可. 才不是因为博主懒得写二分+栈优化呢 代码: #include&l ...
随机推荐
- package.json浅谈
相信很多小伙伴都见过各种各样的Node.js项目,而里面都有一个名为package.json的文件,而这个文件究竟是干什么的呢? 简单的来说,这个文件就是对整个项目的各种情况的配置(也是介绍),下面给 ...
- Java基础-数据类型应用案例展示
Java基础-数据类型应用案例展示 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.把long数据转换成字节数组,把字节数组数据转换成long. /* @author :yinz ...
- python---基础知识回顾(一)(引用计数,深浅拷贝,列表推导式,lambda表达式,命名空间,函数参数逆收集,内置函数,hasattr...)
一:列表和元组(引用计数了解,深浅拷贝了解) 序列:序列是一种数据结构,对其中的元素按顺序进行了编号(从0开始).典型的序列包括了列表,字符串,和元组 列表是可变的(可以进行修改),而元组和字符串是不 ...
- 两个不能同时共存的条件orWhere查询
举例: //我的所有的积分记录 1,我分享的:2,我点击的:(两个条件不能共存) $activity_log = ActivitySharedLog::where(function ($query) ...
- [BZOJ 1013][JSOI 2008] 球形空间产生器sphere 题解(高斯消元)
[BZOJ 1013][JSOI 2008] 球形空间产生器sphere Description 有一个球形空间产生器能够在n维空间中产生一个坚硬的球体.现在,你被困在了这个n维球体中,你只知道球 面 ...
- HDU 1176 免费馅饼 DP类似数塔题
解题报告: 小明走在一条小路上,这条小路的长度是10米,从左到右依次是0到10一共十个点,现在天上会掉馅饼,给出馅饼掉落的坐标和时间,一开始小明的位置是在坐标为5的位置, 他每秒钟只能移动一米的距离, ...
- NVIDIA / Intel 核芯显卡显示 + Nvidia 计算
今天折腾了好久intel集成显卡显示.最后好不容易才全部搞定,这里记录一下. 1. 首先在BIOS里是要打开Intel 核芯显卡的.我把它设置成了主显卡,显示器也接到核心显卡的口上. 重启后, I ...
- 【Python】exe2shellcode,shellcode2exe
用python写这类程序真简洁,要是用C++又不知道得多写多少行代码了. exe2shellcode #! /usr/bin/env python # -*- coding: utf-8 -*- im ...
- 环形缓冲区-模仿linux kfifo【转】
转自:https://blog.csdn.net/vertor11/article/details/53741681 struct kfifo{ uint8_t *buffer; uint32_t i ...
- Linux USB Host-Controller的初始化代码框架分析【转】
转自:http://blog.csdn.net/zkami/article/details/2496770 usb_hcd_omap_probe (const struct hc_driver *dr ...