BZOJ 1492 货币兑换Cash
http://www.lydsy.com/JudgeOnline/problem.php?id=1492
思路:
问题转变为维护一个凸包,每次转移都找凸包上的点,并更新凸壳
可以用splay维护,或者说,可以用cdq分治去维护,左半边构成的凸壳对右半边答案的影响~
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
const double eps=1e-;
double f[];
struct node{
double a,b,rate,x,y,k;
int id;
}p[],tmp[];
int n,stack[];
int read(){
int t=,f=;char ch=getchar();
while (ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
while (''<=ch&&ch<=''){t=t*+ch-'';ch=getchar();}
return t*f;
}
bool cmp(node a,node b){
return a.k>b.k;
}
double getk(int a,int b){
if (!b) return -1e20;
if (fabs(p[a].x-p[b].x)<eps) return 1e20;
return (p[b].y-p[a].y)/(p[b].x-p[a].x);
}
void cdq(int l,int r){
if (l==r){
f[l]=std::max(f[l],f[l-]);
p[l].y=f[l]/(p[l].a*p[l].rate+p[l].b);
p[l].x=p[l].rate*p[l].y;
return;
}
int mid=(l+r)>>;
int l1=l-,l2=mid;
for (int i=l;i<=r;i++)
if (p[i].id<=mid)
tmp[++l1]=p[i];
else
tmp[++l2]=p[i];
for (int i=l;i<=r;i++)
p[i]=tmp[i];
cdq(l,mid);
int top=;
for (int i=l;i<=mid;i++){
while (top>&&getk(stack[top-],stack[top])<getk(stack[top-],i)+eps) top--;
stack[++top]=i;
}
stack[++top]=;int j=;
for (int i=mid+;i<=r;i++){
while (j<top&&getk(stack[j],stack[j+])+eps>p[i].k) j++;
f[p[i].id]=std::max(f[p[i].id],p[stack[j]].x*p[i].a+p[stack[j]].y*p[i].b);
}
cdq(mid+,r);
l1=l,l2=mid+;
for (int i=l;i<=r;i++){
if ((((p[l1].x<p[l2].x)||(fabs(p[l1].x-p[l2].x)<eps&&p[l1].y<p[l2].y))||l2>r)&&l1<=mid) tmp[i]=p[l1++];
else tmp[i]=p[l2++];
}
for (int i=l;i<=r;i++)
p[i]=tmp[i];
}
int main(){
scanf("%d",&n);scanf("%lf",&f[]);
for (int i=;i<=n;i++){
scanf("%lf%lf%lf",&p[i].a,&p[i].b,&p[i].rate);
p[i].k=-p[i].a/p[i].b;
p[i].id=i;
}
std::sort(p+,p++n,cmp);
cdq(,n);
printf("%.3lf",f[n]);
}
Splay代码
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
const double eps=1e-;
int fa[],ch[][];
double lk[],rk[];
double x[],y[],f[],rate[],a[],b[];
int n,root;
int read(){
int t=,f=;char ch=getchar();
while (ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
while (''<=ch&&ch<=''){t=t*+ch-'';ch=getchar();}
return t*f;
}
void rotate(int x,int &rt){
int y=fa[x],z=fa[y],l,r;
if (ch[y][]==x) l=;else l=;r=l^;
if (y!=rt){
if (ch[z][]==y) ch[z][]=x;
else ch[z][]=x;
}else rt=x;
fa[x]=z;fa[y]=x;fa[ch[x][r]]=y;
ch[y][l]=ch[x][r];ch[x][r]=y;
}
void splay(int x,int &rt){
while (x!=rt){
int y=fa[x],z=fa[y];
if (y!=rt){
if ((ch[y][]==x)^(ch[z][]==y)) rotate(x,rt);
else rotate(y,rt);
}
rotate(x,rt);
}
}
void insert(int &k,int Fa,int id){
if (!k){
k=id;
fa[k]=Fa;
return;
}
if (x[k]+eps>=x[id]) insert(ch[k][],k,id);
else insert(ch[k][],k,id);
}
double getk(int i,int j){
if (fabs(x[i]-x[j])<eps) return -1e9;
else return (y[i]-y[j])/(x[i]-x[j]);
}
int pre(int rt){
int k=ch[rt][];int tmp=k;
while (k){
if (lk[k]+eps>=getk(k,rt)) tmp=k,k=ch[k][];
else k=ch[k][];
}
return tmp;
}
int suc(int rt){
int k=ch[rt][];int tmp=k;
while (k){
if (rk[k]<=eps+getk(k,rt)) tmp=k,k=ch[k][];
else k=ch[k][];
}
return tmp;
}
void updata(int k){
splay(k,root);
if (ch[k][]){
int left=pre(root);
splay(left,ch[k][]);ch[left][]=;
lk[k]=rk[left]=getk(k,left);
}else lk[k]=1e9;
if (ch[k][]){
int right=suc(root);
splay(right,ch[k][]);ch[right][]=;
lk[right]=rk[k]=getk(k,right);
}else rk[k]=-1e9;
if (lk[k]<=rk[k]+eps){
root=ch[k][];
ch[root][]=ch[k][];
fa[ch[k][]]=root;
fa[root]=;
rk[root]=lk[ch[k][]]=getk(root,ch[k][]);
}
}
int find(int k,double slop){
if (!k) return ;
if (lk[k]+eps>=slop&&slop+eps>=rk[k]){
return k;
}
if (slop+eps>lk[k]) return find(ch[k][],slop);
else return find(ch[k][],slop);
}
int main(){
n=read();scanf("%lf",&f[]);
for (int i=;i<=n;i++){
scanf("%lf%lf%lf",&a[i],&b[i],&rate[i]);
}
for (int i=;i<=n;i++){
int j=find(root,-a[i]/b[i]);
f[i]=std::max(f[i-],x[j]*a[i]+b[i]*y[j]);
y[i]=f[i]/(a[i]*rate[i]+b[i]);
x[i]=y[i]*rate[i];
insert(root,,i);
updata(i);
}
printf("%.3f\n",f[n]);
}
BZOJ 1492 货币兑换Cash的更多相关文章
- BZOJ 1492 货币兑换 Cash CDQ分治
这题n2算法就是一个维护上凸包的过程. 也可以用CDQ分治做. 我的CDQ分治做法和网上的不太一样,用左边的点建立一个凸包,右边的点在上面二分. 好处是思路清晰,避免了凸包的插入删除,坏处是多了一个l ...
- BZOJ 1492 货币兑换
Description Input 第一行两个正整数\(N,S\),分别表示小Y 能预知的天数以及初始时拥有的钱数. 接下来\(N\)行,第\(K\)行三个实数\(A_{K},B_{K},Rate_{ ...
- BZOJ 1492 [NOI2007] - cash
Description 最初你有 S 块钱, 有 N 天给你来兑换货币, 求最大获利. 一共只有两种货币 A , B . 对于每一天, 给定 3 个系数 A[i], B[i], Rate[i] A[i ...
- BZOJ 1492 货币兑换 cdq分治或平衡树维护凸包
题意:链接 方法:cdq分治或平衡树维护凸包 解析: 这道题我拒绝写平衡树的题解,我仅仅想说splay不要写挂,insert边界条件不要忘.del点的时候不要脑抽d错.有想写平衡树的去看140142或 ...
- 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的数量. 然后就很明显了...平衡 ...
- 【BZOJ】【1492】【NOI207】货币兑换Cash
DP/CDQ分治 orz Hzwer copy了下他的代码……结果在while(j<top......)这一句中把一个括号的位置打错了……找了我一个多小时才找到TAT 很神奇……顺便贴下CDQ的 ...
- bzoj千题计划237:bzoj1492: [NOI2007]货币兑换Cash
http://www.lydsy.com/JudgeOnline/problem.php?id=1492 dp[i] 表示 第i天卖完的最大收益 朴素的dp: 枚举从哪一天买来的在第i天卖掉,或者是不 ...
- 1492: [NOI2007]货币兑换Cash【CDQ分治】
1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 4166 Solved: 1736[Submit][Sta ...
- 【BZOJ-1492】货币兑换Cash DP + 斜率优化 + CDQ分治
1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 3396 Solved: 1434[Submit][Sta ...
随机推荐
- LibCurl编程手册以及代码实例
1. LibCurl编程流程 在基于LibCurl的程序里,主要采用callback function (回调函数)的形式完成传输任务,用户在启动传输前设置好各类参数和回调函数,当满足条件时libcu ...
- httpd与tomcat基于mod_jk整合
搞定在前面述, httpd与tomcat整合方式 当前已知的有 ajp_proxy,mod_jk.so jk connecteor连接器下载地址 http://archive.apache.org/d ...
- Hadoop生态圈技术图谱
当下Hadoop已经成长为一个庞大的体系,貌似只要和海量数据相关的,没有哪个领域缺少Hadoop的身影,下面是一个Hadoop生态系统的图谱,详细的列举了在Hadoop这个生态系统中出现的各种数据工具 ...
- JS(四)
JS的属性好多,方法好多,一下子塞进来真的需要时间消化,很多东西都是当时记得很清楚,但忘得很快,看来需要经常去复习,主要是感觉后面一点的练习题好像少了点,所以就显得不是很熟练. 1.About Tim ...
- [教程] 神器i9100刷基带与内核的方法!(兼带ROOT方法)
http://bbs.hiapk.com/thread-2647905-1-1.html ------何为基带?何为内核? 为什么刷基带,为什么刷内核?!!! 基带:基带(Baseband)是手机中的 ...
- [ES6] Array -- Destructuring and Rest Parameters && for ..of && Arrat.find()
We can use the destructing and rest parameters at the same time when dealing with Array opration. Ex ...
- 模拟jquery封装选择器
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- css中常用的标签
最常用的标签 left 左 top 上 right 右 bottom 下 font 字体 size 大小 width 宽度 height 高度 class 类 label 标签 form 表单 gro ...
- MySQL sql 执行步骤
基本步骤是 1.from 2.join on 3.where 4.group by 5.having 6.order by 7.select 8.distinct ,sum,... ...
- iOS开发之17个常用代码整理
http://www.cnblogs.com/ios8/p/ios-17-code.html