题意:给定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. yii2安装与初始化

    yii2安装与初始化-Yii2学习笔记(一)   一.安装项目: 使用composer下载安装yii2 advanced安装包: composer create-project yiisoft/yii ...

  2. SQL两表之间:根据一个表的字段更新另一个表的字段

    update table1 set field1=table2.field1,field2=table2.field2from table2where table1.id=table2.id

  3. JavaScript字符串相关

      嘛,开头来个定义好了! 首先它是JavaScript基本数据类型之一.字符串由零或多个16位Unicode字符组成的字符序列,用''或者""表示. 它有一些转义序列,例如\n ...

  4. 初入 vue

    基于 vue.js 的前端开发环境,用于前后端分离后的单页应用开发. 搭建 vue 项目 按官方指引,使用 vue-cli 搭建 vue 的项目. # 安装依赖库,建议指定 vue 和 element ...

  5. 好的UI管理后台

    1,https://www.v2ex.com/t/513539 - https://github.com/a54552239/projectManage

  6. Google Colab Free GPU Tutorial【转载】

    转自:https://medium.com/deep-learning-turkey/google-colab-free-gpu-tutorial-e113627b9f5d 1.Google Cola ...

  7. Java中的过滤器,拦截器,监听器---------简单易懂的介绍

    过滤器: 过滤器其主要特点在于:取你需要的东西,忽视那些不需要的东西!在程序中,你希望选择中篇文章中的所有数字,你就可以针对性的挑选数字! 拦截器: 拦截器其主要特点在于:针对你不要的东西进行拦截,比 ...

  8. CDI services--interceptors(拦截器)

    1.拦截器综述 拦截器的功能是定义在Java拦截器规范. 拦截器规范定义了三种拦截点: 业务方法拦截, 生命周期回调侦听, 超时拦截(EJB)方法. 在容器的生命周期中进行拦截 1 2 3 4 pub ...

  9. luogu P2327 [SCOI2005]扫雷

    很好的一道题,仔细思索(在y^3 dalao的帮助下)可以发现答案只有0 1 2三种情况 直接枚举第一位有没有雷,就可以递推了qwq 附上y^3大佬的blogs https://blog.csdn.n ...

  10. ajax的网上解析

    /* 用XMLHTTPRequest来进行ajax异步数据交交互*/ 主要有几个步骤: //1.创建XMLHTTPRequest对象 //最复杂的一步 if (window.XMLHttpReques ...