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 ...
随机推荐
- 初识python面向对象编程
初识python面向对象编程 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.面向过程的程序设计思想 #!/usr/bin/env python #_*_coding:utf-8 ...
- MyEclipse设置字体和背景的方法
可以根据自己喜好设置MyEclipse工作空间中的字体和背景颜色. 1.选择菜单Window→Preferences. 2.设置字体的方法.选择General→Appearance→Colors an ...
- Codeforces 543 B. World Tour
http://codeforces.com/problemset/problem/543/B 题意: 给定一张边权均为1的无向图. 问至多可以删除多少边,使得s1到t1的最短路不超过l1,s2到t2的 ...
- Windows一个文件夹下面最多可以放多少文件
一个文件夹下面最多可以放多少文件 这个问题其实我也不知道,不过我们可以来进行个测试,看看文件夹下面最多能放多少个文件. 那么怎么来测试这样一个问题呢,很显然我们一个个的去建立文件是不现实的,没那么多时 ...
- 网络_OSI模型_数据包传输
2017年1月12日, 星期四 网络_OSI模型_数据包传输 1. 网络_源主机_局域网_交换机_路由器_目标主机 2. OSI7七层_TCP/IP精简 OSI 7层: 应用层 ...
- raphael.js 给元素 hover 添加glow() 外发光
用raphael.js 给 svg画布里面添加个元素,嗯就圓好了,男人一般都喜欢圆形的东西,比如xx , xxx , 还有xxx $(document).ready(function() { var ...
- 20155303 2016-2017-2 《Java程序设计》第六周学习总结
20155303 2016-2017-2 <Java程序设计>第六周学习总结 课堂笔记 高效学习法推荐 看视频学习(2h)→ 以代码为中心看课本,思考运行结果并验证(3h)→ 课后作业验证 ...
- IE 11 使用 flexbox 垂直居中 bug
不要使用 min-height 改为 height 即可 caniuse: https://caniuse.com/#search=flexbox
- ocky勒索软件恶意样本分析2
locky勒索软件恶意样本分析2 阿尔法实验室陈峰峰.胡进 前言 随着安全知识的普及,公民安全意识普遍提高了,恶意代码传播已经不局限于exe程序了,Locky敲诈者病毒就是其中之一,Locky敲诈者使 ...
- deeplearning.ai学习LSTM
一.LSTM架构与公式 这里的a<t>表示的就是原始输出,y<t>表示的就是经过softmax的输出,c<t>相当于状态.u(update)代表是输入门,f代表遗忘 ...