zoukankan      html  css  js  c++  java
  • hdu4296 贪心

    E - 贪心

    Crawling in process... Crawling failed Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

    Submit Status

    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 w i and strength s i. When floors are stacked up, each floor has PDV(Potential Damage Value) equal to (Σw j)-s i, where (Σw j) 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 <= 10 5) denoting the number of building’s floors. The following N lines specify the floors. Each of them contains two integers w i and s i (0 <= w i, s i <= 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,同时每一块木板会有一个
    pdv数值,计算方法为(Σw j)-s i,即所有在其上的木板的重量之和减去他的承受力,问你怎么样放置才能使pdv的最大值
    (pdv最大的那块木板)最小。
    思路分析:首先,题目要求的是pdv最大的那块木板的pdv值,并不是让所有木板的pdv之和最小,读题时一定要注意!
    另外,很显然我们需要对这些木板进行排序,但是我们应该怎么排才能使最大的pdv值最小呢?换言之,我们以什么样的
    标准来决定哪块木板在上,哪块木板在下。
    对于相邻放置的两块板,设两块板为i,j他们上面的重量为sum
    1) a=sum-si;b=sum+wi-sj;

     交换两个板的位置

    2)a'=sum+wj-si;b'=sum-sj;

    如果1优于2,求解得有效的条件为wj-si>wi-sj

    即wj+sj>wi+si

    所以按si+wi的和排序贪心即可。

    贪心好奇妙,感觉贪心虽然是人的天性,但是有的人会贪,有的人不会贪,

    很多时候并没有什么道理可言,全靠个人直觉,但是得考虑得全面,我感觉

    贪心策略的确定基本可以有两个想法,一个是全自己想,然后自己出数据,

    不断的使自己的策略接近正确答案。二是可以先搞少的数据,两个或三个,

    列公式确定贪心策略。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn=100000+100;
    struct nod
    {
        int w;
        int s;
    };
    nod f[maxn];
    bool cmp(nod a,nod b)
    {
        return a.s+a.w<b.s+b.w;
    }
    int main()
    {
       int n;
       while(scanf("%d",&n)!=EOF)
       {
           __int64 ma=0,sum,t;
           for(int i=0;i<n;i++)
           scanf("%d%d",&f[i].w,&f[i].s);
           sort(f,f+n,cmp);
           sum=f[0].w;
           for(int i=1;i<n;i++)
           {
               t=sum-f[i].s;
               if(t>ma) ma=t;
               sum+=f[i].w;
           }
           printf("%I64d ",ma);
       }
        return 0;
    }

     
  • 相关阅读:
    看代码所学1
    金额,重量,成绩不使用浮点数来表示,而使用整形
    安全风控的CAP原理和BASE思想
    Git操作
    项目上线规范以及一些词汇
    水滴筹面试
    Sping框架中的注解详解
    Restful技术
    @crossorigin注解跨域
    解决Ubuntu14.04下vi编辑器不能使用方向键和退格键问题
  • 原文地址:https://www.cnblogs.com/xuejianye/p/5437695.html
Copyright © 2011-2022 走看看