BZOJ 1150 CTSC2007 数据备份Backup 堆+馋

简介:

标题效果:给定一个长度n1的序列,要求选出k个不相邻的数使得和最小 
费用流显然能跑。并且显然过不去- - 
考虑用堆模拟费用流 
一个错误的贪心是每次取最小。这样显然过不去例子 
我们把【每次取最小】改为【每次选择一个区间取反】。用堆来维护这些区间就可以 
每次取出最小的区间,然后将两边合并 
(比方如今堆里有[1,3][4,4][5,5])这三个区间,我取走了[4,4]并计入答案。那么我删除[1,3]和[5,5]这两个区间,并增加[1,5]这个区间,权值为[1,3]的权值+[5,5]的权值-[4,4]的权值 
因为是费用流所以不用考虑边界问题 直接把[0,0]和[n+1,n+1]设为INF就可以

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 100100
using namespace std;
struct abcd{
    int x,val;
    abcd() {}
    abcd(int _,int __):
        x(_),val(__) {}
    bool operator < (const abcd &a) const
    {
        if( val != a.val )
            return val > a.val ;
        return x < a.x ;
    }
    bool operator == (const abcd &a) const
    {
        return x==a.x && val==a.val ;
    }
};
namespace Heap{
    priority_queue<abcd> heap,del_mark;
    void Insert(abcd x)
    {
        heap.push(x);
    }
    void Delete(abcd x)
    {
        del_mark.push(x);
    }
    void Pop()
    {
        while( del_mark.size() && heap.top()==del_mark.top() )
            heap.pop(),del_mark.pop();
        heap.pop();
    }
    abcd Top()
    {
        while( del_mark.size() && heap.top()==del_mark.top() )
            heap.pop(),del_mark.pop();
        return heap.top();  
    }
}
int n,k,ans,a[M],val[M];
namespace Union_Find_Set{
    int fa[M],rank[M],l[M],r[M];
    int Find(int x)
    {
        if(!fa[x]||fa[x]==x)
            return fa[x]=x;
        return fa[x]=Find(fa[x]);
    }
    void Union(int x,int y)
    {
        int _l=l[x=Find(x)];
        int _r=r[y=Find(y)];
        if(rank[x]>rank[y])
            swap(x,y);
        if(rank[x]==rank[y])
            ++rank[y];
        fa[x]=y;
        l[y]=_l;r[y]=_r;
    }
}
int main()
{
    using namespace Union_Find_Set;
    int i;
    cin>>n>>k;
    for(i=1;i<=n;i++)
        scanf("%d",&a[i]);
    for(i=1;i<=n+1;i++)
        l[i]=i-1,r[i]=i+1;
    Heap::Insert(abcd(1,val[1]=0x3f3f3f3f));
    Heap::Insert(abcd(n+1,val[n+1]=0x3f3f3f3f));
    for(i=2;i<=n;i++)
        Heap::Insert(abcd(i,val[i]=a[i]-a[i-1]));
    for(i=1;i<=k;i++)
    {
        abcd temp=Heap::Top();Heap::Pop();
        ans+=temp.val;
        int _l=Find(l[temp.x]),_r=Find(r[temp.x]);
        Heap::Delete(abcd(_l,val[_l]));
        Heap::Delete(abcd(_r,val[_r]));
        temp.val=val[_l]+val[_r]-val[temp.x];
        Union(_l,temp.x);
        Union(temp.x,_r);
        temp.x=Find(temp.x);
        Heap::Insert(temp);
        val[temp.x]=temp.val;
    }
    cout<<ans<<endl;
    return 0;
}

版权声明:本文博主原创文章,博客,未经同意不得转载。







本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/4889678.html,如需转载请自行联系原作者


相关文章
|
5月前
|
Oracle 关系型数据库
|
5月前
|
存储 算法 安全
【服务器数据恢复】HP EVA存储结构&原理&数据恢复方案
EVA是虚拟化存储,在工作过程中,EVA存储中的数据会不断地迁移,再加上运行在EVA上的应用都比较繁重,磁盘负载高,很容易出现故障。EVA是通过大量磁盘的冗余空间和故障后rss冗余磁盘动态迁移保护数据。但是如果磁盘掉线数量到达一个临界点,EVA存储就会崩溃。
【服务器数据恢复】HP EVA存储结构&原理&数据恢复方案
|
Oracle 关系型数据库 Linux
一次把RMAN备份速度提高6倍的工作笔记
这是我给一个使用Oracle数据库的客户做一个RMAN备份优化的工作笔记。
140 0
|
Oracle 关系型数据库 Linux
这样做,RMAN备份速度可提高6倍!
本例是我在实际工作中帮客户做的一个Oracle备份优化案例。
|
SQL 存储 关系型数据库
面试高频:为什么数据删了,表空间不变呢?
大家好前面我们大概了解了为什么MySQL在查询数据的时候,有些时候会 &quot;抖&quot; 一下。以及分析了刷脏页的策略问题以及连坐机制。今天介绍一下为什么delete from表名,表的大小还是没有变小!
面试高频:为什么数据删了,表空间不变呢?
|
缓存 Oracle 关系型数据库
[20171204]关于rman备份疑问4.txt
[20171204]关于rman备份疑问4.txt --//上午排除我几天在做rman测试的疑问. --//链接如下:http://blog.itpub.net/267265/viewspace-2148029/ --//顺便测试备份集包含5个数据文件的情况(本来不想做,还是做看看),验证自己的判断是否正确.
1121 0
|
Oracle 关系型数据库 测试技术
[20171201]关于rman备份疑问3.txt
[20171201]关于rman备份疑问3.txt --//上午排除我几天在做rman测试的疑问. --//链接如下:http://blog.itpub.net/267265/viewspace-2148029/ --//顺便测试备份集包含4,5个数据文件的情况,验证自己的判断是否正确.
959 0
|
Oracle 关系型数据库 测试技术
[20171130]关于rman备份疑问.txt
[20171130]关于rman备份疑问.txt --//前面测试太乱,重新做一些rman as copy相关测试. 1.环境: SCOTT@book> @ &r/ver1 PORT_STRING                    VERSION  ...
835 0