bzoj1148

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

很常见的排序贪心题。。。。。。
假设我们得到了一个最优序列,记s[n]=w[1]+w[2]+...+w[n]
对于第n个和第n+1个,剩余容量为:
min(c[n]-s[n-1],c[n+1]-s[n-1]-w[n])
如果交换第n个和第n+1个,剩余容量为:
min(c[n+1]-s[n-1],c[n]-s[n-1]-w[n+1])
因为我们得到的是一个最优序列,所以不交换比交换优,所以:
min(c[n]-s[n-1],c[n+1]-s[n-1]-w[n])  > min(c[n+1]-s[n-1],c[n]-s[n-1]-w[n+1])
容易知道c[n]-s[n-1]>c[n]-s[n-1]-w[n+1],c[n+1]-s[n-1]-w[n]<c[n+1]-s[n-1]
所以就是:
c[n+1]-s[n-1]-w[n]>c[n]-s[n-1]-w[n+1]
c[n]+w[n]<c[n+1]+w[n+1]
所以就是按ci+wi从小到大排序。
我们先按ci+wi从小到大排序,然后一个一个取,如果不能去,就在已取的中找质量最大的,看替换或会不会更优,这个可以用优先队列。
#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=200000;



int N;

struct Tdata{LL C,W;}data[maxN+100];



inline bool cmp(Tdata a,Tdata b){return a.C+a.W<b.C+b.W;}



struct cmp2{inline bool operator()(Tdata a,Tdata b){return a.W<b.W;}};

priority_queue<Tdata,vector<Tdata>,cmp2> Q;

LL ans;



int main()

  {

      freopen("bzoj1148.in","r",stdin);

      freopen("bzoj1148.out","w",stdout);

      int i;

      N=gint();

      re(i,1,N)data[i].C=LL(gint()),data[i].W=LL(gint());

      sort(data+1,data+N+1,cmp);

      re(i,1,N)

        if(ans<=data[i].C)

          {

              ans+=data[i].W;

              Q.push(data[i]);

          }

        else

          if(data[i].W<Q.top().W && ans-Q.top().W<=data[i].C)

            {

                ans-=Q.top().W;

                Q.pop();

                ans+=data[i].W;

                Q.push(data[i]);

            }

      cout<<Q.size()<<endl;

      cout<<ans<<endl;

      return 0;

  }
View Code

 

你可能感兴趣的:(ZOJ)