hdu 4296 Buildings (贪心)

http://acm.hdu.edu.cn/showproblem.php?pid=4296

题意:

给出n个石板的重量w和它的承受能力s,将这n个石板累在一起,这样每个石板都有一个PDV = (Σwj)-si   , (Σwj)表示在i石板上的石板的重量和,我们计算每块石板的PDV如果是负数说明石板不会被压坏,如果是正数则表示石板会被压坏,要求我们确定一个顺序是的所有正数的最大值最小。一次来表示石板的最大承压能力;

思路:

开始读题读了老长时间都没读懂,最后还是把题意理解错了,试了分别按s,w排序都不对,郁闷了。最后才看懂了题意,我们要求的是正数的最大值的最小,我们只要保证每次可能出现正数时他是可能的里面最小的即可,假设n个石板一个都没选,首先压在地面上的总重量为s = p[1].w +p[2].w + ....+ p[n].w;  当我们计算第一个时要从1到n个里面选一个,其PDV = s - w[i] - s[i] = s - (w[i] + s[i])我们只要保证每次选出来的PDV最小即可,而每次选的时候s是确定,我们只要选出候选集里面的w + s 最大的即可,所以按w + s排个贪心的处理一下就好。

View Code
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <string>

#define CL(a,num) memset((a),(num),sizeof(a))
#define iabs(x)  ((x) > 0 ? (x) : -(x))
#define Min(a,b) (a) > (b)? (b):(a)
#define Max(a,b) (a) > (b)? (a):(b)

#define ll __int64
#define inf 0x7f7f7f7f
#define MOD 100000007
#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0)
#define test puts("<------------------->")
#define maxn 10000007
#define M 100007
#define N 100007
using namespace std;
//freopen("din.txt","r",stdin);

struct node{
    int s,w;
    int sum;
}p[N];

int cmp(node a,node b){
    return a.sum > b.sum;
}
int main(){
   // freopen("din.txt","r",stdin);
    int n,i;
    while (~scanf("%d",&n)){
        ll s = 0;
        for (i = 0; i < n; ++i){
            scanf("%d%d",&p[i].w,&p[i].s);
            p[i].sum = p[i].w + p[i].s;
            s += p[i].w;
        }
        sort(p,p + n,cmp);
        ll ans = 0;
        for (i = 0; i < n; ++i){
            s -= p[i].w;
            ll tmp = s - p[i].s;
            if (tmp > 0) ans = max(ans,tmp);
        }
        printf("%I64d\n",ans);
    }
    return 0;
}

 

 

 

 

 

posted @ 2012-09-17 21:37  E_star  阅读(466)  评论(0)    收藏  举报