码迷,mamicode.com
首页 > 其他好文 > 详细

手套(线段树+贪心)

时间:2017-09-29 00:33:34      阅读:146      评论:0      收藏:0      [点我收藏+]

标签:void   ret   code   str   out   比较   计算   using   name   

你现在有N对手套,但是你不小心把它们弄乱了,需要把它们整理一下。N对手套被一字排开,每只手套都有一个颜色,被记为0~N-1,你打算通过交换把每对手套都排在一起。由于手套比较多,你每次只能交换相邻两个手套。请你计算最少要交换几次才能把手套排整齐(只需要手套配对,不需要手套按从小到大的编号排序)。

30%的数据N≤9;
60%的数据N≤1000;
100%的数据N≤200,000。

输入格式 

输入第一行一个N,表示手套对数。
第二行有2N个整数,描述了手套的颜色。每个数都在0~N-1之间,且每个数字都会出现恰好两次。

输出格式 

一行,包含一个数,表示最少交换次数。

输入样例 

2
1 0 1 0

输出样例 

1

将中间两个手套交换过来,颜色序列变成1 1 0 0。

题解:我们考虑第1只手套,和他配对的是第a只,我们把右边的移到最左边总是最优的,如果不是右边移到最左边,就可能会出现另一对手套配对时要跨过当前的手套,而我们把右边的移到最左边就可以避免这种情况。所以我们每次把右边的手套移到左边,但是我们又不能用数组去模拟,那么怎么知道右边的手套移动了多少次呢?

假如枚举到左边的手套在a,且未完成配对,右边的手套在b,则需要移动的次数为(b-a-1)再减去中间已经移到左边的手套数,对于中间移走的手套数,我们考虑用线段树维护,以下标为关键字,1表示移走,求个区间和就可以了。

#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<fstream>
#include<iostream>
#include<cstring>
using namespace std;

int n,a[400050],id[400020],tree[4500000],vis[400020];
long long ans;

void Updata(int root,int l,int r,int wei,int x)
{
    if (l==r&&r==wei)
    {
        tree[root]+=x;
        return;
    }
    int mid=(l+r)/2;
    if (wei<=mid) Updata(root*2,l,mid,wei,x);
    else Updata(root*2+1,mid+1,r,wei,x);
    tree[root] = tree[root*2]+tree[root*2+1];
}

int Query(int root,int l,int r,int L,int R)
{
    if (L<=l&&r<=R) return tree[root];
    if (R<l||L>r) return 0;
    int mid=(l+r)/2;
    return Query(root*2,l,mid,L,R)+Query(root*2+1,mid+1,r,L,R);
}

int main()
{
    freopen("2067.in","r",stdin);
    freopen("2067.out","w",stdout);
    scanf("%d",&n);
    for (int i=1; i<=2*n; i++)
    {
        scanf("%d",&a[i]);
        id[a[i]] = i;
    }
    for (int i=1; i<=2*n; i++)
    Updata(1,1,2*n,i,1);
    for (int i=1; i<=2*n; i++)
    if (vis[a[i]]==0)
    {
        ans = ans+Query(1,1,2*n,i+1,id[a[i]]-1);
        vis[a[i]]=1;
        Updata(1,1,2*n,id[a[i]],-1);
    }
    printf("%lld\n",ans);
    return 0;
} 

 

手套(线段树+贪心)

标签:void   ret   code   str   out   比较   计算   using   name   

原文地址:http://www.cnblogs.com/Janous/p/7608823.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!