zoukankan      html  css  js  c++  java
  • 【HOJ2430】Counting the Algorithms-区间维护

    题目大意:有一个长度为2*N的数列,其中1~N的每个整数都出现2次,要将它们两两删除,删除一个元素以后,另一个元素也被消除,并获得等于它们位置标号之差的绝对值的分数,问删除完所有元素之后所能获得的最大分数是多少。

    做法:可以发现,当一对元素被另一对元素包含时,先删除外面的一对元素是最优的;如果两对元素所表示的区间有一部分相交,那么先删哪一对结果都是一样的。所以,我们只需维护每对元素之间所剩的元素个数,从前往后删除即可。

    以下是本人代码(树状数组):

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    int n,pos[100010]={0},a[200010]={0},c[200010]={0}; //pos[i]:值为i的一对元素的后面那个元素的位置
    int ans;
    
    int lowbit(int i)
    {
      return i&(-i);
    }
    
    void add(int x,int a)
    {
      for(int i=x;i<=2*n;i+=lowbit(i))
        c[i]+=a;
    }
    
    int sum(int x)
    {
      int s=0;
      for(int i=x;i>0;i-=lowbit(i))
        s+=c[i];
      return s;
    }
    
    int main()
    {
      while(scanf("%d",&n)!=EOF)
      {
        memset(c,0,sizeof(c));
    	memset(pos,0,sizeof(pos));
        ans=0;
    	for(int i=1;i<=2*n;i++)
    	{
    	  scanf("%d",&a[i]);
    	  pos[a[i]]=i;
    	  add(i,1);
    	}
    	for(int i=1;i<=2*n;i++)
    	{
    	  if (a[i])
    	  {
    	    ans+=sum(pos[a[i]])-sum(i);
    	    add(i,-1);
    	    add(pos[a[i]],-1);
    		a[pos[a[i]]]=0;a[i]=0;
    	  }
    	}
    	printf("%d
    ",ans);
      }
      
      return 0;
    }
    


  • 相关阅读:
    hdu 5734 Acperience
    报错解决
    测试代码出错
    fast rcnn训练自己数据小结
    top命令
    读csv文件
    计算机的屏幕坐标
    用virtualenv构建一个新的python环境,这个新的环境在这个创建的文件夹下
    python tips
    将目录下所有文件名修改为统一格式
  • 原文地址:https://www.cnblogs.com/Maxwei-wzj/p/9793987.html
Copyright © 2011-2022 走看看