搭积木(block)
【问题描述】
小 OY 是一个喜欢搭积木的孩子,他有一天决定向小 C 展示他特别的搭积木
技巧。
现在一条直线上从左到右有 n 个位置,标号 1..n,第 i 个位置坐标为 x_i。
每个位置上都预先叠好了一些积木,其中第 i 个位置上叠了 a_i 块积木。
小 OY 一开始会向小 C 指定 1..n 中的某个位置 s,然后,他在第 0 秒从位置
s 出发,开始搭积木。
他可以做这些动作:
1、向左移动 1 个单位坐标,用时 1 秒。
2、向右移动 1 个单位坐标,用时 1 秒。
3、从当前位置顶部拿起一块积木,瞬间完成。
4、把拿着的积木叠到当前位置,瞬间完成。
由于小 OY 很小,任意时刻他手上至多只能带一块积木。
当时间到达第 T 秒时,小 OY 不会再进行移动。这时候,如果位置 s 的积木
叠得越高,就显得小 OY 叠积木本领越强。
现在,小 OY 在思考,如果他的移动策略足够高明,并且位置 s 也选定得恰
到好处,那么第 T 秒时位置 s 最多能叠到多少块积木呢?
【输入】
输入文件名:block.in
第一行两个数 n、T。
第二行 n 个严格递增的整数,第 i 个数为 x_i。
第三行 n 个非负整数,第 i 个数为 a_i。
【输出】
输出文件名:block.out
第一行一个数,为从最优的 s 出发在最高明的移动策略下,第 T 秒位置 s 至
多能叠到多少块积木。
【数据范围】
测试点 1..3:n≤100,T≤1000
测试点 4..5:a_i≤1
测试点 6..7:x_i = i
测试点 1..8:n≤10 5
测 试点 1..10: 1≤n≤ 5*10 5 ,0≤ T≤ 10 18 ,0≤ a_i≤10 4 ,0 ≤ x_i≤10 9
算法 1
先枚举 s,然后从近到远把其他位置的积木一个个拿到 s 来,直到时间 T 耗尽
为止。复杂度 O(nT)。
算法 2
优化一下算法 1,假设当前取到的最左、最右位置分别为 l、r,然后每次一下
取 min(a[l],a[r])个,如果取完后时间不超过 T 就取完,否则直接计算还能取几
个。由于每次左右指针都至少有一个会往边界移,复杂度 O(n^2)。
算法 3
先二分答案 k,问题成了:求把位置 s 叠到高度 k 所需的最短时间。
从左到右枚举 s,那么肯定是从前 k 近的地方搬来积木。我们想象每个位置 i
的 a[i]个积木是从左到右紧密排列在坐标 x[i]的,令 l 表示前 k 近的积木最左的
那块,r 表示最右的那块,随着 s 的右移,左边的积木们越来越远,右边的越来越
近,那么 l、r 是非降的。
暴力移动指针的话,复杂度是 O(Σ a[i])的。
正解:
在算法3的基础上如果时间不超过就尽可能取完,因为l,r非降,所以可以用
类似单调队列的思想,移动左右
lc表示a[l]未取的积木,rc表示a[r]已取的积木
先得出把1堆到k的最短时间,得到r和rc
之后考虑把s位置右移,右移后在不考虑l,r的移动的情况下
等价于把1~i的积木右移,i+1~r的积木向右撤回
移动完更新时间后,如果l比r距离s远,那么不如把l积木不取,来取r的积木
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
int n;
ll a[],x[];
ll s[],T,ans;
ll sum(int l,int lc,int r,int rc)
{
if (l==r)
return rc-lc;
return (s[r-]-s[l]+a[l]-lc+rc);
}
bool check(ll need)
{int i;
int l=,r=n+;
ll lc=,rc=;
ll s=;
ll cur=;
for (i=;i<=n;i++)
{
if (s+a[i]<=need)
{s+=a[i];cur+=(x[i]-x[])*a[i];}
else
{
rc=need-s;r=i;cur+=(x[i]-x[])*rc;
break;
}
}
if (cur<=T) return ;
for (i=;i<=n;i++)
{
cur+=(x[i]-x[i-])*(sum(l,lc,i,)-sum(i,,r,rc));
while (r<=n&&(x[i]-x[l])>(x[r]-x[i]))
{
int p=min(a[l]-lc,a[r]-rc);
cur+=(x[r]-x[i]-x[i]+x[l])*p;
lc+=p;rc+=p;
if (lc>=a[l]) l++,lc=;
if (rc>=a[r]) r++,rc=;
}
if (cur<=T) return ;
}
return ;
}
int main()
{int i;
cin>>n>>T;
T/=;
for (i=;i<=n;i++)
{
scanf("%lld",&x[i]);
}
for (i=;i<=n;i++)
{
scanf("%lld",&a[i]);
s[i]=s[i-]+a[i];
}
ll l=,r=s[n];
while (l<=r)
{
ll mid=(l+r)/;
if (check(mid)) ans=mid,l=mid+;
else r=mid-;
}
cout<<ans;
}
搭积木(block)的更多相关文章
- Leo 搭积木
Leo 搭积木[问题描述]Leo是一个快乐的火星人,总是能和地球上的 OIers玩得很 high.2012 到了, Leo 又被召回火星了,在火星上没人陪他玩了,但是他有好多好多积木,于是他开始搭积木 ...
- Android_就像小朋友“搭积木”一样。
就像小朋友“搭积木”一样.感觉这句话很有意思.完整的话是这样的: Android提供了大量功能丰富的UI组件,开发者只要按一定规律把这些UI组件组合起来 --就像小朋友“搭积木”一样,把这些UI组件搭 ...
- XJOI1657&Codevs1255搭积木【树状动规】
搭积木 一种积木搭建方式,高为H的积木,最底层有M个积木,每一层的积木数是他的低一层的积木数+1或-1.总共有N个积木.(且每行积木数不超过10)比如上图N=13 H=6 M=2. 输入格式: 第一行 ...
- 蓝桥杯-搭积木-java
/* (程序头部注释开始) * 程序的版权和版本声明部分 * Copyright (c) 2016, 广州科技贸易职业学院信息工程系学生 * All rights reserved. * 文件名称: ...
- codevs 3249 搭积木
提交地址:http://codevs.cn/problem/3249/ 3249 搭积木 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目 ...
- [Luogu 2816]宋荣子搭积木
Description saruka非常喜欢搭积木,他一共有n块积木.而且saruka的积木很特殊,只能一块块的竖着摞,可以摞很多列.说过saruka的是特殊的积木了,这些积木都非常智能,第i块积木有 ...
- 搭积木(java)-蓝桥杯
搭积木小明最近喜欢搭数字积木,一共有10块积木,每个积木上有一个数字,0~9.搭积木规则:每个积木放到其它两个积木的上面,并且一定比下面的两个积木数字小.最后搭成4层的金字塔形,必须用完所有的积木.下 ...
- 《陪孩子像搭积木一样学编程》,一起来玩Scratch(1)使用Scratch编程的基本流程
编程是一件很有趣的事情.初次接触编程,你可能不知所措,别担心,这并不复杂.首先,为了让读者对编程有大概的了解,可以把编写Scratch程序的过程分成7个步骤(如图1.8).注意,这是理想状态.在实际的 ...
- 整数N分解,搭积木,离散数学中的母函数,ZOJ(1163)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1163 解题报告: 将整数N分解为:两个及以上的不重复的整数,最流 ...
随机推荐
- C语言第六次博客作业--数据类型
一.PTA实验作业 题目1:区位码输入法 1. 本题PTA提交列表 2. 设计思路 (1)定义整型变量code放区位码,areacode放区码,digitcode放位码,one放个位数,two放十位数 ...
- MyGod--Beta版本前期报告
下一阶段需要改进完善的功能 1.完善购买功能,商品购买后,将生成申请订单,卖家将收到提醒.卖家在完成订单后,可以选择完成订单,商品将下架. 2.完善搜索功能,将界面中的搜索功能添加进去(简单考虑只搜索 ...
- Argparse简易教程
Argparse简易教程 原文:Argparse Tutorial 译者:likebeta 本教程是对于Python标准库中推荐使用的命令行解析模块argparse的简单介绍. PS:还有其他两个模块 ...
- win7下,使用django运行django-admin.py无法创建网站
安装django的步骤: 1.安装python,选择默认安装在c盘即可.设置环境变量path,值添加python的安装路径. 2.下载ez_setup.py,下载地址:http://peak.tele ...
- 关于webService发布的wsdl中的import问题解决
大家都知道jdk1.6及以后都支持了对webService的原生态的支持:它在发布时会生成一个wsdl和一个xsd(一个类只生成一个xsd)所以就保留了引用关系,如下: <?xml versio ...
- bzoj千题计划244:bzoj3730: 震波
http://www.lydsy.com/JudgeOnline/problem.php?id=3730 点分树内对每个节点动态维护2颗线段树 线段树以距离为下标,城市的价值为权值 对于节点x的两棵线 ...
- JAVA_SE基础——28.封装
黑马程序员blog... 面向对象三大特征:1. 封装2. 继承3 多态. 今天我们先学习第一大特征,封装. 封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式. 好处: 1. 将变 ...
- 构建自己的PHP框架--构建模版引擎(3)
之前我们实现了最简单的echo命令的模版替换,就是将{{ $name }}这样一段内容替换成<?php echo $name ?>. 现在我们来说下其他的命令,先来回顾下之前的定义 输出变 ...
- 关于 Ubuntu Linux 16.04中文版的 root 权限及桌面登录问题
新接触 Ubuntu 的朋友大多会因为安装中没有提示设置 root 密码而不太清楚是什么原因. 起初 Ubuntu 团队希望安装尽可能的简单. 不使用 root , 在安装期间的两个用户交互步骤可以省 ...
- AngularJS1.X学习笔记8-自定义指令(上)
AngulaJS的指令是一种非常强大的特性,一个ng-repeat就能让我们非常方便的展示一个数据列表,指令相当于是一个组件,为我们将一些东西封装起来了,提供了复用的可能性.个人认为自定义指令还是比较 ...