bzoj1150

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1150

很明显我们只会连相邻的两幢楼
所以样例就是:2 1 2 6
根据题目意思我们不能取相邻的两个数
用贪心的思想,先取最小的1 然后 删去 2 1 2 再 加上 3 表示不取1而去1的左右两边
但是要注意边界
如 1 2 3 4
很明显如果取1,就一定不会取2,取2不会更优
可以用set来代替堆
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<fstream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<utility>
#include<set>
#include<bitset>
#include<vector>
#include<functional>
#include<deque>
#include<cctype>
#include<climits>
#include<complex>
//#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj
 
using namespace std;

typedef long long LL;
typedef double DB;
typedef pair<int,int> PII;
typedef complex<DB> CP;

#define mmst(a,v) memset(a,v,sizeof(a))
#define mmcy(a,b) memcpy(a,b,sizeof(a))
#define re(i,a,b)  for(i=a;i<=b;i++)
#define red(i,a,b) for(i=a;i>=b;i--)
#define fi first
#define se second
#define m_p(a,b) make_pair(a,b)
#define SF scanf
#define PF printf
#define two(k) (1<<(k))

template<class T>inline T sqr(T x){return x*x;}
template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;}
template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;}

const DB EPS=1e-9;
inline int sgn(DB x){if(abs(x)<EPS)return 0;return(x>0)?1:-1;}
const DB Pi=acos(-1.0);

inline int gint()
  {
        int res=0;bool neg=0;char z;
        for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
        if(z==EOF)return 0;
        if(z=='-'){neg=1;z=getchar();}
        for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
        return (neg)?-res:res; 
    }
inline LL gll()
  {
      LL res=0;bool neg=0;char z;
        for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
        if(z==EOF)return 0;
        if(z=='-'){neg=1;z=getchar();}
        for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
        return (neg)?-res:res; 
    }

const int maxN=100000;

int N,K;
int dist[maxN+100];
int cnt;
struct Tlist
  {
      int l,r,id;
        LL val;
      inline friend bool operator <(Tlist a,Tlist b){return (a.val!=b.val)?a.val<b.val:a.id<b.id;}
    }
list[2*maxN+100];
set<Tlist> S;
LL ans;

int main()
  {
      freopen("bzoj1150.in","r",stdin);
      freopen("bzoj1150.out","w",stdout);
      int i;
      N=gint();K=gint();
      re(i,1,N)dist[i]=gint();
      sort(dist+1,dist+N+1);
      red(i,N,2)dist[i]=dist[i]-dist[i-1];
      re(i,1,N-1)dist[i]=dist[i+1];
      N--;
      cnt=N;
      re(i,1,N)
          {
              list[i].id=i;
              if(i!=1) list[i].l=i-1;
              if(i!=N) list[i].r=i+1;
              list[i].val=LL(dist[i]);
              S.insert(list[i]);
            }
        ans=0;
        while(K--)
          {
              int t=S.begin()->id;
              if(list[t].l==0)
                {
                    ans+=list[t].val;
                    S.erase(list[t]);
                    S.erase(list[list[t].r]);
                    list[list[list[t].r].r].l=0;
                }
              else
              if(list[t].r==0)
                {
                    ans+=list[t].val;
                    S.erase(list[t]);
                    S.erase(list[list[t].l]);
                    list[list[list[t].l].l].r=0;
                }
              else
                {
                  ans+=list[t].val;
                    S.erase(list[t]);
                  if(list[t].l!=0)S.erase(list[list[t].l]);
                  if(list[t].r!=0)S.erase(list[list[t].r]);
                  ++cnt;
                    list[cnt].id=cnt;
                    list[cnt].val=list[list[t].l].val+list[list[t].r].val-list[t].val;
                  list[cnt].l=list[list[t].l].l;
                  list[cnt].r=list[list[t].r].r;
                  if(list[cnt].l!=0) list[list[cnt].l].r=cnt;
                  if(list[cnt].r!=0) list[list[cnt].r].l=cnt;
                  S.insert(list[cnt]);
              }
          }
        cout<<ans<<endl;
        return 0;
    }
View Code

 

posted @ 2015-07-15 21:07  maijing  阅读(200)  评论(0编辑  收藏  举报