题意:给定n个圆柱体的半径和高,输入顺序即圆柱体的编号顺序。现在规定,只有编号和体积均大于另一个圆柱体,才能放到另一个圆柱体的体积上面。求能叠加的最大体积是多少。

酝酿了我三天,才理解。自己敲个代码,还超时了,但是把思路记录一下吧,实在不知道哪里超时了。

思路:dp+线段树维护。本质是求递增序列的最大和。设dp[i]表示以编号为i的圆柱体为顶部的圆柱。大问题拆分成子问题:dp[i]=max(dp[j])  +  v[i] ,j表示可以放在i号圆柱体下的合法圆柱体,即体积和编号均小于 i 。但是如果直接枚举状态,然后 去暴力搜索合法的 dp[j],会超时,因此,第二层for循环,合法的dp[j]用线段树维护(但是我还是超时了uhnnnnnnn,,无语啊)。先确定要维护的区间,维护区间为v即每个圆柱体的体积,再把体积从小到大排序。再去遍历状态参量  i  ,每一次找到 v[i]在体积区间当中所处的位置。然后在体积区间里小于v[i]的部分里找最大的dp[j]。其实一开始我有个地方不理解,就是只维护体积区间,每次去查1至 i-1 区间里的最大的dp[j],但是我觉得编号不一定满足 j<i,事实证明想多了,因为每一次更新v[i]所处位置的dp[i]值时,,是按照编号顺序来更新的,也就是说哪些体积比它小,但是编号比他大的在后面才会更新,当前这步是不会更新的。

本题,线段树的精髓,每当求出一个位置的dp[i]的时候,都去包含此位置的区间,并且由于还是按照输入顺序来更新的,所以不存在体积小,但是序号大的情况。

上个超时代码吧。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll; struct Node
{
int l,r;
int dat;
}t[*]; long long dp[*];
long long v[*];
int H[*];
long long ans=;
const double PI=acos(-1.0);
int n; void build(int p,int l,int r)
{
t[p].l=l,t[p].r=r;
//int mid=(l+r)>>1;
if(l==r){ t[p].dat=;return;}
int mid=(l+r)>>;
build(p*,,mid);
build(p*+,mid+,r);
t[p].dat=max(t[p*].dat,t[p*+].dat);
} ll query(int p,int l,int r)
{
if(l>r) return ;
if(l<=t[p].l&&t[p].r<=r) return t[p].dat;
int mid=(t[p].l+t[p].r)>>;
ll val=-<<;
if(mid>=l) val=max(val,query(p*,l,r));
if(mid<r) val=max(val,query(p*+,l,r));
return val;
} void update(int p,int x,int v)
{
if(t[p].l==t[p].r){t[p].dat=v;return;}
int mid=(t[p].l+t[p].r)>>;
if(x<=mid) update(p*,x,v);
else update(p*+,x,v);
t[p].dat=max(t[p*].dat,t[p*+].dat);
} int main()
{
cin>>n;
int r,h;
for(int i=;i<=n;i++)
{
cin>>r>>h;
v[i]=r*r*h;
H[i]=v[i];
dp[i]=v[i];
} sort(H+,H++n);
build(,,n);
for(int i=;i<=n;i++)
{
int cur=lower_bound(H+,H++n,v[i])-H;
dp[i]=max(dp[i],query(,,cur-)+v[i]);
update(,cur,dp[i]);
ans=max(ans,dp[i]);
} printf("%.15lf",PI*ans);
return ;
}

629D - Babaei and Birthday Cake的更多相关文章

  1. codeforces 629D. Babaei and Birthday Cake

    题目链接 大意就是给出一个序列, 然后让你从中找出一个严格递增的数列, 使得这一数列里的值加起来最大. 用线段树, 先将数列里的值离散,然后就是线段树单点更新, 区间查询最值. 具体看代码. #inc ...

  2. Codeforces 629D Babaei and Birthday Cake(树状数组优化dp)

    题意: 线段树做法 分析: 因为每次都是在当前位置的前缀区间查询最大值,所以可以直接用树状数组优化.比线段树快了12ms~ 代码: #include<cstdio> #include< ...

  3. Codeforces 629D Babaei and Birthday Cake(线段树优化dp)

    题意: n个蛋糕编号从小到大编号,j号蛋糕可以放在i号上面,当且仅当j的体积严格大于i且i<j,问最终可得的最大蛋糕体积. 分析: 实质为求最长上升子序列问题,设dp[i]从头开始到第i位的最长 ...

  4. codeforces 629D D. Babaei and Birthday Cake (线段树+dp)

    D. Babaei and Birthday Cake time limit per test 2 seconds memory limit per test 256 megabytes input ...

  5. Codeforces Round #343 (Div. 2) D. Babaei and Birthday Cake 线段树维护dp

    D. Babaei and Birthday Cake 题目连接: http://www.codeforces.com/contest/629/problem/D Description As you ...

  6. 【20.19%】【codeforces 629D】Babaei and Birthday Cake

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  7. Codeforces 629D Babaei and Birthday Cakes DP+线段树

    题目:http://codeforces.com/contest/629/problem/D 题意:有n个蛋糕要叠起来,能叠起来的条件是蛋糕的下标比前面的大并且体积也比前面的大,问能叠成的最大体积 思 ...

  8. Codeforces Round #343 (Div. 2) D - Babaei and Birthday Cake 线段树+DP

    题意:做蛋糕,给出N个半径,和高的圆柱,要求后面的体积比前面大的可以堆在前一个的上面,求最大的体积和. 思路:首先离散化蛋糕体积,以蛋糕数量建树建树,每个节点维护最大值,也就是假如节点i放在最上层情况 ...

  9. CF-629 D - Babaei and Birthday Cake (离散化 + 线段树|树状数组)

    求上升子序列的最大和.O(n^2)会暴力,在查询的时候要用线段树维护 因为权值是浮点数,故先离散化一下,设第 i 个位置的权值,从小到大排名为 id.那么dp转移中 \[d[i] = max(d[i] ...

随机推荐

  1. tomcat体系结构

    总体架构解析 Server: 一个StandardServer类实例就表示一个Server容器,TOMCAT启动的时候首先会启动一个Server,一个Server包括多个Service Service ...

  2. JVM性能调优总结

    引自其它博客 : https://www.cnblogs.com/donaldlee2008/p/5469685.html 注 : 该条同样适用于Tomcat调优 调优配置说明 堆大小设置JVM 中最 ...

  3. ASM

    一. 磁盘阵列 RAID 5 二. STRRPE 三. LAT 四. [root@localhost ~]# fdisk /dev/sdjDevice contains neither a valid ...

  4. webpack(6)-模块热替代&tree shaking

    模块热替换(hot module replacement 或 HMR) 模块热替换(hot module replacement 或 HMR)是 webpack 提供的最有用的功能之一.它允许在运行时 ...

  5. JAVA判断是否是手机设备访问

    package com.common.util; import java.util.regex.Matcher;import java.util.regex.Pattern; /** * 检测是否为移 ...

  6. Oracle 11g R2 Backup Data Pump(数据泵)之expdp/impdp工具

    Oracle Data Pump(以下简称数据泵)是Oracle 10g开始提供的一种数据迁移工具,同时也被广大DBA用来作为数据库的逻辑备份工具和体量较小的数据迁移工具.与传统的数据导出/导入工具, ...

  7. TextField widgets require a Material widget ancestor

    TextField widget需要被包裹在Scaffold widget中,否则会报错

  8. python类之魔法方法

    python类之魔法方法: class A(object): def __init__(self,x): self.x = x def __neg__(self): print('-v') def _ ...

  9. 关于UR=A的测试

    当数据库在nomount,mount或者restricted这类特殊状态下,同时动态监听显示状态为BLOCKED,客户端无法直接连接到实例,此时可通过配置UR=A进行连接.最常见的场景就是10g版本的 ...

  10. CDI services--Scope(生命周期)&&EL.(Sp El)

    一.EL/SpEL 1.EL语言(CDI与表达式语言(EL)集成,允许在JavaServer Faces页面或JavaServer Pages页面中直接使用任何组件) 1)概述:EL是JSP内置的表达 ...