zoukankan      html  css  js  c++  java
  • bzoj1150[CTSC2007]数据备份Backup

    bzoj1150[CTSC2007]数据备份Backup

    题意:

    n个地方,在其中找k对地方,每个地方只属于一对。定义一对的费用为两个地方的距离,求最小费用总和。

    题解:

    把所有相邻地方距离放入一个集合中,每次取出最小的那个距离x,然后将相邻两边的距离l,r合并成l+r-x。如果这个x缺一边相邻,则将剩下那一边的距离去掉,如果缺两边相邻,则不用去掉。这个找相邻的过程用链表维护,同时找最小距离以及删距离的操作用set维护(好像也可以用手写堆,然而我不会)。

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <set>
     5 #define inc(i,j,k) for(int i=j;i<=k;i++)
     6 #define maxn 100010
     7 using namespace std;
     8 
     9 inline int read(){
    10     char ch=getchar(); int f=1,x=0;
    11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
    12     while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    13     return f*x;
    14 }
    15 int n,k,a[maxn]; long long ans;
    16 struct sn{
    17     int pos,v;
    18     bool operator < (const sn &x)const{return v!=x.v?v<x.v:pos<x.pos;}
    19 };
    20 set<sn>s;
    21 struct nd{int v,l,r;}; nd nds[maxn];
    22 int main(){
    23     n=read(); k=read(); int st=read(); inc(i,1,n-1){int x=read(); a[i]=x-st; st=x;} n--;
    24     inc(i,1,n){s.insert((sn){i,a[i]}); nds[i]=(nd){a[i],i-1,i+1>n?0:i+1};}
    25     inc(i,1,k){
    26         set<sn>::iterator xx=s.begin(); int x=xx->pos; ans+=xx->v; s.erase(xx);
    27         if(!nds[x].l&&!nds[x].r)continue;
    28         else if(!nds[x].r){
    29             xx=s.find((sn){nds[x].l,nds[nds[x].l].v}); s.erase(xx); nds[nds[nds[x].l].l].r=0;
    30         }else if(!nds[x].l){
    31             xx=s.find((sn){nds[x].r,nds[nds[x].r].v}); s.erase(xx); nds[nds[nds[x].r].r].l=0;
    32         }else{
    33             nds[x].v=nds[nds[x].l].v+nds[nds[x].r].v-nds[x].v;
    34             xx=s.find((sn){nds[x].l,nds[nds[x].l].v}); s.erase(xx);
    35             xx=s.find((sn){nds[x].r,nds[nds[x].r].v}); s.erase(xx);
    36             s.insert((sn){x,nds[x].v});
    37             nds[x].l=nds[nds[x].l].l; nds[x].r=nds[nds[x].r].r; nds[nds[x].l].r=x; nds[nds[x].r].l=x;
    38         }
    39     }
    40     printf("%lld",ans); return 0;
    41 }

    20160902

  • 相关阅读:
    在VS2010下,用C语言编写pthread多线程程序的配置
    java帮助文档系列JDK1.5 JDK1.6 JDK1.7官方中英完整版下载
    瑜伽练习day02----适合练习瑜伽时听的歌曲
    瑜伽练习day01----瑜伽练习的好处,坏处
    抛出错误Debug Assertion Failed!
    stringstream的基本用法
    AWS中S3的Bucket桶访问策略
    AWS中SQS的几项使用注意
    AWS在.Net中连接数据库时发生认证错误的解决办法
    .Net捕捉配置或程序错误
  • 原文地址:https://www.cnblogs.com/YuanZiming/p/5839578.html
Copyright © 2011-2022 走看看