题目描述

箱子再分配问题需要解决如下问题:
 (1)一共有N个物品,堆成M堆。
 (2)所有物品都是一样的,但是它们有不同的优先级。
 (3)你只能够移动某堆中位于顶端的物品。
 (4)你可以把任意一堆中位于顶端的物品移动到其它某堆的顶端。若此物品是当前所有物品中优先级最高的,可以直接将之删除而不用移动。
(5)求出将所有物品删除所需的最小步数。删除操作不计入步数之中。
 (6)只是一个比较难解决的问题,这里你只需要解决一个比较简单的版本:
         不会有两个物品有着相同的优先级,且M=2

输入

第一行是包含两个整数N1,N2分别表示两堆物品的个数。
接下来有N1行整数按照从顶到底的顺序分别给出了第一堆物品中的优先级,数字越大,优先级越高。
再接下来的N2行按照同样的格式给出了第二堆物品的优先级。

输出

对于每个数据,请输出一个整数,即最小移动步数。

样例输入

3 3
1
4
5
2
7
3

样例输出

6

提示

1<=N1+N2<=100000

题解

   讲个真实的故事:说从前有个小傻瓜,她打了一个50分的模拟,但她对这个模拟很不满意,认为它T得太厉害。后来她想到了一个60分的优化方法,于是她打了出来,又把它交了上去,但是这个优化有个小缺陷,然后0分。。。明明是一道很清楚的题啊。今天考完试之后,似乎有很多同学觉得自己离正解和高分很近,然而结果却很糟,我不也是这样吗?虽然这样的事很可惜,可是事出有因。好多数据结构很久没打过,早上稍微看了一下树状数组,但是没有细致复习,总觉得打线段树也是一样(这代码量根本没法比)。甚至于改完了之后在cogs上提交,因为太急躁三遍都没打对文件名,这就是心态问题了。吃一堑长一智,不是但愿如此,而是必须如此。
int lowbit(int x)
{
return x&(-x);
}
for(int i=1;i<=n;i++)
{
int temp=lowbit(i);
for(int j=i-t+1;j<=i;j++)
d[i]+=a[j];
}
int getsum(int x)
{
int jg=0;
while(x>0)
{
jg+=d[x];
x-=lowbit(x);
}
return jg;
}
void update(int x,int y)
{
while(x<=n)
{
d[x]+=y;
x+=lowbit(x);
}
}
先把物品的优先级离散一下,再把第一堆倒序和第二堆对在一起,标记出各优先级的物品所在的位置,然后用树状数组处理;优先级最高的物品特殊处理,此后每个物品到下一个物品的步数等于两物品前缀和之差的绝对值-1,每移动一个物品就把它的权值变为0即可。
for(int i=n;i>1;i--)
{
jg+=abs(getsum(wz[i])-getsum(wz[i-1]))-1;
update(wz[i],-1);
}
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int sj=;
int n1,n2,n,yx[sj],a1,a2,wz[sj],a[sj],d[sj],t;
long long jg;
struct WP
{
int ord;
long long vl;
}wp[sj];
int comp(const WP&a,const WP&b)
{
return a.vl<b.vl;
}
int lowbit(int x)
{
return x&(-x);
}
int getsum(int x)
{
int res=;
while(x>)
{
res+=d[x];
x-=lowbit(x);
}
return res;
}
void update(int x,int y)
{
while(x<=n)
{
d[x]+=y;
x+=lowbit(x);
}
}
int main()
{
scanf("%d%d",&n1,&n2);
n=n1+n2;
for(int i=;i<=n;i++)
{
scanf("%lld",&wp[i].vl);
wp[i].ord=i;
}
sort(wp+,wp+n+,comp);
for(int i=;i<=n;i++)
yx[wp[i].ord]=i;
for(int i=;i<=n1;i++)
{
a[n1-i+]=;
wz[yx[i]]=n1-i+;
}
for(int i=n1+;i<=n;i++)
{
a[i]=;
wz[yx[i]]=i;
}
if(wz[n]>n1) jg=wz[n]-n1-;
else jg=n1-wz[n];
for(int i=;i<=n;i++)
{
t=lowbit(i);
for(int j=i-t+;j<=i;j++)
d[i]+=a[j];
}
for(int i=n;i>;i--)
{
jg+=abs(getsum(wz[i])-getsum(wz[i-]))-;
update(wz[i],-);
}
printf("%lld",jg);
//while(1);
return ;
}
 

删除物品[JLOI2013]的更多相关文章

  1. [bzoj3192][JLOI2013]删除物品(树状数组)

    3192: [JLOI2013]删除物品 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 872  Solved: 508[Submit][Status ...

  2. 洛谷 P3253 [JLOI2013]删除物品 解题报告

    P3253 [JLOI2013]删除物品 题目描述 箱子再分配问题需要解决如下问题: (1)一共有\(N\)个物品,堆成\(M\)堆. (2)所有物品都是一样的,但是它们有不同的优先级. (3)你只能 ...

  3. 3192: [JLOI2013]删除物品

    3192: [JLOI2013]删除物品 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1366 Solved: 794 [Submit][Statu ...

  4. [bzoj3192][JLOI2013]删除物品_树状数组_栈

    删除物品 bzoj-3192 JLOI-2013 题目大意:给你n个物品,分成2堆.所有的物品有不同的优先级.我只可以将一堆中的堆顶移动到另一个堆的堆顶.而如果当前物品是全局所有物品中优先级最高的,我 ...

  5. bzoj 3192: [JLOI2013]删除物品

    Description   箱子再分配问题需要解决如下问题:  (1)一共有N个物品,堆成M堆.  (2)所有物品都是一样的,但是它们有不同的优先级.  (3)你只能够移动某堆中位于顶端的物品.  ( ...

  6. [JLOI2013]删除物品

    嘟嘟嘟 只要每一次将优先级最高的上面的物品移走,就一定能保证是最优解. 所以我们只要想办法简化这个模拟移物品的过程,看完了题解后,发现可以这么想,我们可以把两个栈头碰头的挨在一起,然后设一个指针代表两 ...

  7. BZOJ3192:[JLOI2013]删除物品——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=3192 箱子再分配问题需要解决如下问题: (1)一共有N个物品,堆成M堆. (2)所有物品都是一样的 ...

  8. BZOJ3192: [JLOI2013]删除物品(splay)

    Description   箱子再分配问题需要解决如下问题:  (1)一共有N个物品,堆成M堆.  (2)所有物品都是一样的,但是它们有不同的优先级.  (3)你只能够移动某堆中位于顶端的物品.  ( ...

  9. [JLOI2013]删除物品 树状数组

    当时考试时间剩下太短了然后就挂掉了..其实是个简单的数据结构. 话说一看最小还以为是动规呢.. 将两堆头对头排.比如样例就是 541|273 因为是必须有优先级次序,依次拿的话,看优先级大小相邻的两个 ...

随机推荐

  1. CSS实现两端对齐效果

    CSS实现两端对齐效果 两端对齐,从概念上来说,其实不难理解.如果不明白什么叫两端对齐,可以玩玩word等办公软件. 下面谈谈如何实现文本的两端对齐.我所知道的大概有以下几种方法 text-align ...

  2. 源码安装zabbix_server服务端

    按照上一篇安装lnmp环境:http://www.cnblogs.com/armo/p/6067716.html 保证lnmp正常运行,然后安装zabbix_server 安装依赖 yum -y in ...

  3. C#中的Dictionary的使用

    在工作中有时候会用到Dictionary,由于自己之前没用过,参考了一下前人和先辈的实践,仿照着写了一个Test,第一次用还不是很熟练,要多实践练习才能用的得心应手,写代码重在敲键盘,以此为诫.(主要 ...

  4. 进入MVC处理通道

    这一篇主要讲如何通过Asp.net处理管道把请求交给MVC进行处理的(进入MVC处理通道). 首先来看一下经典的Asp.net处理管道的生命周期. 我们知道一个ASP.NET应用程序可以有多个Http ...

  5. Mysql 根据时间戳按年月日分组统计

    Mysql 根据时间戳按年月日分组统计create_time时间格式SELECT DATE_FORMAT(create_time,'%Y%u') weeks,COUNT(id) COUNT FROM ...

  6. jQuery(二) jQuery对Ajax的使用

    学习使我快乐!嘿 --WH 一.jQuery使用Ajax 想要了解jQuery如何使用Ajax,并且体会到它所带来的方便性,那么就得了解原始的Ajax是如何编写的,是怎样的繁琐,然后和Jquery的代 ...

  7. 如何利用php+android+新浪sae服务器做一个app下载应用

    功能简介:提供一个app下载的平台,类似于appstore,上面有很多app可供下载 实现基本思路:利用android,在手机桌面建立一个图标,点击该图标不是打开app应用,而是跳转到一个web页面, ...

  8. Python如何调用新浪api接口的问题

    前言:这些天在研究如何调用新浪开放平台的api分析新浪微博用户的数据 成果:成功调用了新浪api获取了用户的一些个人信息和无数条公共微博 不足:新浪开放平台访问有限制,返回的数据着实有限,不足以分析问 ...

  9. DOCKER 从入门到放弃(一)

    前言 关于docker的各种概念已有各位大神珠玉在前,请各位自行查看,本系列的目的是各种详细操作步骤 各种概念特别推荐CloudMan的3篇blog: http://www.cnblogs.com/C ...

  10. VS2015 +Qt5 串口工具

    简单的小工具是VS2015 + Qt5.6.1实现的,界面部分是Qt实现,串口是封装的WinAPI,把串口收发模块封装成了个Serialport.dll 供Qt界面调用. 由于VS2015需要CRT运 ...