[NOI2007 Day1] 货币兑换 Cash
vijos P1508 / BZOJ 1492
膜拜了这么久的cdq分治,终于有机会亲自来写了。虽然这个思想很好理解,先做前一半,计算前一半对后一半的影响,再做后一半。但是由于我这个傻Ⅹ,以前既没有做过斜率优化,也没有做过维护凸包之类,花了好久时间捣鼓具体做法,而且理解思路后写起来还是有点难度的。
主要网上的解题各有各的思路,有的是F数组存最多多少B券,有的是存最多多少A券,虽然大同小异,但是一开始我没意识到所以orz了。
参考资料:
《从Cash谈一类分治算法的应用》——cdq
同时,我也很大程度上参考了这里的代码。=v=好不容易找了一个易读的C++代码…差不多就是翻译了过来,我的程序里写了“//?”是修改过的。
这么神的题一定要好好温习,同时也要好好学splay啊,至今没有成功码过一次QAQ
program cash;
//orz cdq
const eps=0.000000001;
maxn=;
type typeq=record
k,a,b,r:real;
pos:longint;
end;
typep=record
x,y:real;
end;
var i,j,n,s:longint;
//a,b,r:array[..] of longint;
f:array[..maxn] of real;
q,nq:array[..maxn] of typeq;
p,np:array[..maxn] of typep;
st:array[..maxn] of longint;
function max(a,b:real):real;
begin
if a>b then exit(a) else exit(b);
end; procedure qsort(l,r:longint);
var i,j:longint;
mid:real;
temp:typeq;
begin
i:=l;j:=r;mid:=q[(l+r) div ].k;
while i<=j do
begin
while q[i].k<mid do inc(i);
while q[j].k>mid do dec(j);
if i<=j then
begin
temp:=q[i];q[i]:=q[j];q[j]:=temp;
inc(i);dec(j);
end;
end;
if i<r then qsort(i,r);
if j>l then qsort(l,j);
end; function getk(a,b:longint):real;
begin
if a= then exit(-maxlongint+);
if b= then exit(maxlongint);
if (p[a].x-p[b].x<=eps) and (p[a].x-p[b].x>=-eps) then exit(-maxlongint+);
exit((p[a].y-p[b].y)/(p[a].x-p[b].x));
end; procedure solve(l,r:longint);
var mid,l1,l2,top,i,j:longint;
begin
if l=r then
begin
f[l]:=max(f[l-],f[l]);
p[l].y:=f[l]/(q[l].a*q[l].r+q[l].b);
p[l].x:=p[l].y*q[l].r;
exit;
end;
mid:=(l+r) div ;l1:=l;l2:=mid+;
for i:=l to r do
if q[i].pos<=mid then
begin
nq[l1]:=q[i];inc(l1); //?
end
else
begin
nq[l2]:=q[i];inc(l2); //?
end;
for i:=l to r do q[i]:=nq[i];
solve(l,mid);
top:=;
for i:=l to mid do
begin
while (top>=) and (getk(i,st[top])+eps>getk(st[top],st[top-])) do dec(top);
inc(top);st[top]:=i;
end;
j:=;
for i:=r downto mid+ do //update
begin
while (j<top) and (q[i].k<getk(st[j],st[j+])+eps) do inc(j);
f[q[i].pos]:=max(f[q[i].pos],p[st[j]].x*q[i].a+p[st[j]].y*q[i].b);
end;
solve(mid+,r);
l1:=l;l2:=mid+;
for i:=l to r do //?
if ((p[l1].x<p[l2].x) or (l2>r)) and (l1<=mid) then
begin
np[i]:=p[l1];inc(l1);
end
else
begin
np[i]:=p[l2];inc(l2);
end;
for i:=l to r do
p[i]:=np[i];
end; begin{main}
readln(n,f[]);
for i:= to n do
begin
readln(q[i].a,q[i].b,q[i].r);
q[i].k:=-q[i].a/q[i].b;
q[i].pos:=i;
end;
qsort(,n); //sort array q[i].k
solve(,n); //cdq solve
writeln(f[n]::);
end.
Cash
测试数据 #0: Accepted, time = 0 ms, mem = 12876 KiB, score = 10
测试数据 #1: Accepted, time = 0 ms, mem = 12876 KiB, score = 10
测试数据 #2: Accepted, time = 0 ms, mem = 12876 KiB, score = 10
测试数据 #3: Accepted, time = 0 ms, mem = 12876 KiB, score = 10
测试数据 #4: Accepted, time = 0 ms, mem = 12876 KiB, score = 10
测试数据 #5: Accepted, time = 15 ms, mem = 12876 KiB, score = 10
测试数据 #6: Accepted, time = 296 ms, mem = 12880 KiB, score = 10
测试数据 #7: Accepted, time = 312 ms, mem = 12880 KiB, score = 10
测试数据 #8: Accepted, time = 578 ms, mem = 12876 KiB, score = 10
测试数据 #9: Accepted, time = 609 ms, mem = 12876 KiB, score = 10
Accepted, time = 1810 ms, mem = 12880 KiB, score = 100
[NOI2007 Day1] 货币兑换 Cash的更多相关文章
- BZOJ 1492: [NOI2007]货币兑换Cash( dp + 平衡树 )
dp(i) = max(dp(i-1), x[j]*a[i]+y[j]*b[i]), 0<j<i. x, y表示某天拥有的最多钱去买金券, 金券a和金券b的数量. 然后就很明显了...平衡 ...
- bzoj1492[NOI2007]货币兑换Cash cdq分治+斜率优化dp
1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 5541 Solved: 2228[Submit][Sta ...
- bzoj千题计划237:bzoj1492: [NOI2007]货币兑换Cash
http://www.lydsy.com/JudgeOnline/problem.php?id=1492 dp[i] 表示 第i天卖完的最大收益 朴素的dp: 枚举从哪一天买来的在第i天卖掉,或者是不 ...
- [BZOJ1492][NOI2007]货币兑换Cash(斜率优化+CDQ分治)
1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 5838 Solved: 2345[Submit][Sta ...
- BZOJ1492: [NOI2007]货币兑换Cash 【dp + CDQ分治】
1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec Memory Limit: 64 MB Submit: 5391 Solved: 2181 [Submit][S ...
- [BZOJ1492] [NOI2007]货币兑换Cash 斜率优化+cdq/平衡树维护凸包
1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 5907 Solved: 2377[Submit][Sta ...
- 【BZOJ1492】[NOI2007]货币兑换Cash 斜率优化+cdq分治
[BZOJ10492][NOI2007]货币兑换Cash Description 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和 B纪念券(以下简称B券).每 ...
- 1492: [NOI2007]货币兑换Cash【CDQ分治】
1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 4166 Solved: 1736[Submit][Sta ...
- [BZOJ1492] [NOI2007] 货币兑换Cash(cdq分治+斜率优化)
[BZOJ1492] [NOI2007] 货币兑换Cash(cdq分治+斜率优化) 题面 分析 dp方程推导 显然,必然存在一种最优的买卖方案满足:每次买进操作使用完所有的人民币:每次卖出操作卖出所有 ...
随机推荐
- 《zw版·Halcon-delphi系列原创教程》 Halcon分类函数005·graphics-obj,基本绘图单元,包括线段、矩形、椭圆、圆形
<zw版·Halcon-delphi系列原创教程> Halcon分类函数005·graphics-obj,基本绘图单元,包括线段.矩形.椭圆.圆形 graphics-obj,基本绘图单元, ...
- 十七、Java基础---------集合框架之Map
前两篇文章中介绍了Collection框架,今天来介绍一下Map集合,并用综合事例来演示. Map<K,V> Map<K,V>:Map存储的是键值对形式的元素,它的每一个元素, ...
- 【实践】jQuery实现三联联动
网上看过很多关于联动的jq或js代码,最近班上的前端大神教了我一种比网上还简单的jq联动方法,自己琢磨过之后确实比其他方法更简单更简洁所以在这里分享一下 先上html代码 <div id=&qu ...
- ql Server 高频,高并发访问中的键查找死锁解析
死锁对于DBA或是数据库开发人员而言并不陌生,它的引发多种多样,一般而言,数据库应用的开发者在设计时都会有一定的考量进而尽量避免死锁的产生.但有时因为一些特殊应用场景如高频查询,高并发查询下由于数据库 ...
- 批处理命令——set
[1]set命令简介 set,设置. [2]set命令使用 1. 打印系统环境变量.set命令可以打印系统所有的环境变量信息. 应用示例:新建文本文件,命名为set_sys,修改文件类型为bat,用N ...
- @weakify, @strongify ObjC的Block中使用weakSelf/strongSelf @weakify/@strongify
首先要说说什么时候使用weakSelf和strongSelf. 下面引用一篇博客<到底什么时候才需要在ObjC的Block中使用weakSelf/strongSelf>的内容: Objec ...
- Oracle子查询(嵌套查询)
概念: 所谓子查询,即一个select语句中嵌套了另外的一个或者多个select语句 需求:查找和Smith同部门的所有员工的id和last_name 目标: 员工id,last_name from: ...
- 20个Linux服务器安全强化建议(二)
接上文,继续介绍一些Linux服务器的安全配置. #6.强密码策略. 当我们使用 useradd.usermod 命令创建或维护用户账号时,确保始终应用强密码策略.例如,一个好的密码至少包括8个字 ...
- How to change owner of PostgreSql database?
ALTER DATABASE name OWNER TO new_owner;
- jQuery实现两个按钮的位置互换
页面上有2个按钮A和B.点击按钮A和按钮B互换位置 ,点击按钮B和按钮A互换位置.应该如何实现? html代码如下: <body> <!--页面上有2个按钮A和B. 点击按钮A和按钮 ...