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 ...
随机推荐
- Javascript Image Slider 插件注册机
Javascript Image Slider 是个不错的轮播插件,兼容 IE 7.0+, Firefox 1.5+, Chrome 1.0+, Safari 3+, Opera 9.0+, Nets ...
- 【整理】Git相关资料
http://book.51cto.com/art/201107/278731.htm http://book.51cto.com/art/201107/278828.htm
- HTML5页面开发的基础性模板
分享一个HTML5页面开发的基础性模板,包含了两个版本: 开发版本 注释版本 开发版本 <!DOCTYPE html> <html> <head> <meta ...
- UVALive 6176 Faulhaber's Triangle
题目链接 http://acm.sdibt.edu.cn/vjudge/ojFiles/uvalive/pdf/61/6177.pdf 题意是 给定一个数n,代表着一共有n个人,且他们的身高从1到n ...
- 03 uni-app框架学习:轮播图组件的使用
1.轮播图组件的使用 参照官方文档 2.在页面上加入这个组件 3.在页面中引去css样式 并编写样式 ps:upx单位是什么 简单来说 就相当于小程序中的rpx 是一个自适应的单位 会根据屏幕宽度自动 ...
- CSS marging相关
一.margin可以为负值 在盒模型中,内容区的width/height.padding.border都不能为负值,但是margin例外,它可以为负值. margin负值的本质,在于它改变了元素在普通 ...
- gbk文件转为utf8文件
convmv -f gbk -t utf- --notest -r ./
- Convert Expression to Reverse Polish Notation
Given an expression string array, return the Reverse Polish notation of this expression. (remove the ...
- 【windows】在控制面板卸载软件的时候,出现2502,2503的问题
1. 打开“任务管理器”,找到“详细信息”的页签,将“explorer.exe”的进程结束任务 2.菜单栏的“文件”-->"建立新任务"--> 输入Explorer.e ...
- selenium玩转svg操作
今天写脚本发现页面有svg结构,里面的元素无法定位,查找很多资料,然后就记录下来 初步尝试直接在页面中获取svg中包含元素的xpath,直接利用selenium方法访问,无法捕获到相关元素信息. SV ...