zoukankan      html  css  js  c++  java
  • 删除物品[JLOI2013]

    题目描述

    箱子再分配问题需要解决如下问题:
     (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=100010;
    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=0;
        while(x>0)
        {
           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=1;i<=n;i++)
        {
           scanf("%lld",&wp[i].vl);
           wp[i].ord=i;
        }
        sort(wp+1,wp+n+1,comp);
        for(int i=1;i<=n;i++)
           yx[wp[i].ord]=i;
        for(int i=1;i<=n1;i++)
        {
          a[n1-i+1]=1;
          wz[yx[i]]=n1-i+1;
        }
        for(int i=n1+1;i<=n;i++)
        {
          a[i]=1;
          wz[yx[i]]=i;
        }
        if(wz[n]>n1)  jg=wz[n]-n1-1;
        else jg=n1-wz[n];
        for(int i=1;i<=n;i++)
        {
            t=lowbit(i);
            for(int j=i-t+1;j<=i;j++)
              d[i]+=a[j];
        }
        for(int i=n;i>1;i--)
        {
            jg+=abs(getsum(wz[i])-getsum(wz[i-1]))-1;
            update(wz[i],-1);
        }
        printf("%lld",jg);
        //while(1);
        return 0;
    }
     
    南风知我意,吹梦到西洲。
  • 相关阅读:
    ejs不能读取js变量??????
    技术架构
    测试框架那些事儿
    如何跨团队带项目?
    自定义网址导航站-聚享导航
    vue+node+mongodb前后端分离博客系统
    聚享导航chrome插件发布
    NuxtJS实战,一个博客系统
    Essay3.0发布,基于JavaScript的前后端同构博客系统
    小程序开发中的一些坑和技巧
  • 原文地址:https://www.cnblogs.com/moyiii-/p/7182838.html
Copyright © 2011-2022 走看看