HDU 4296 Buildings 【贪心】


传送门:HDU 4296



Buildings
Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Problem Description
Have you ever heard the story of Blue.Mary, the great civil engineer? Unlike Mr. Wolowitz, Dr. Blue.Mary has accomplished many great projects, one of which is the Guanghua Building.
The public opinion is that Guanghua Building is nothing more than one of hundreds of modern skyscrapers recently built in Shanghai, and sadly, they are all wrong. Blue.Mary the great civil engineer had try a completely new evolutionary building method in project of Guanghua Building. That is, to build all the floors at first, then stack them up forming a complete building.
Believe it or not, he did it (in secret manner). Now you are face the same problem Blue.Mary once stuck in: Place floors in a good way.
Each floor has its own weight wi and strength si. When floors are stacked up, each floor has PDV(Potential Damage Value) equal to (Σwj)-si, where (Σwj) stands for sum of weight of all floors above.
Blue.Mary, the great civil engineer, would like to minimize PDV of the whole building, denoted as the largest PDV of all floors.
Now, it’s up to you to calculate this value.

  
Input
There’re several test cases.
In each test case, in the first line is a single integer N (1 <= N <= 105) denoting the number of building’s floors. The following N lines specify the floors. Each of them contains two integers wi and si (0 <= wi, si <= 100000) separated by single spaces.
Please process until EOF (End Of File).

  
Output
For each test case, your program should output a single integer in a single line - the minimal PDV of the whole building.
If no floor would be damaged in a optimal configuration (that is, minimal PDV is non-positive) you should output 0.

  
Sample Input
3
10 6
2 3
5 4
2
2 2
2 2
3
10 3
2 5
3 3

Sample Output
1
0
2




题意:
给定N个物体,每个物体有两个参数w,s。 w代表它自身的重量; s代表它的强度。现在要把这些物体叠在一起,会产生一个PDV值,PDV= ∑ w j \sum w_j wj-si。( ∑ w j \sum w_j wj指在他之上的物体的总质量的和)将这些楼层随意排序,每个楼层都会得到不同的PDV值,每个排序都会有个最大的PDV值,题目要求让我们使最大的PDV值最小。

题解:
我们假设有两个楼层i,j,sum,指他们上面的楼层质量总和,那么他们有两种情况:

1.i在上,j在下。各自PDV为:sum-si ; sum+wi-sj;

2.j在下,i在下。各自PDV为:sum-sj ; sum+wj-si;

为了使最大的PDV值最小,我们假设情况1为最小情况,那么就应该满足:

sum+wi-sj < sum+wj-si
即:
wi+si < wj+sj

所有我们只要对每个楼层排个序,然后找最大值即可;



贪心的题目想解出来好随缘啊TAT,这题我试了几个排序,一开始想按单位质量的承受量来排序即(w/s),错了之后又觉得是按(w-s)来排序。
做这东西全靠个人直觉啊,我就是属于那种不会贪的TAT




AC代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const int N=110000;
struct Node
{
  int w,s;
  int v;
}floors[N];
int n;
bool cmp(Node a,Node b)
{
  return a.v<b.v;
}
int main()
{
  while(scanf("%d",&n)!=EOF)
  {
    for(int i=0;i<n;i++)
    {
      scanf("%d%d",&floors[i].w,&floors[i].s);
      floors[i].v=floors[i].w+floors[i].s;
    }
    sort(floors,floors+n,cmp);
    ll tmp=0;
    ll maxn=-inf;
    for(int i=0;i<n;i++)
    {
      ll temp=tmp-floors[i].s;
      maxn=max(maxn,temp);
      tmp+=floors[i].w;
    }
    if(maxn<=0) printf("0\n");
    else printf("%lld\n",maxn);
  }
  return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值