zoukankan      html  css  js  c++  java
  • hdu 4296 Buildings 夜

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

    此题仅需用 w+s 的值进行从小到大的排序即可  注意  结果可能超32位

    证明  只需要证明相邻的即可 因为它们不会影响前面的PDV 也不会影响后面的PDV

    假设 w1+s1  <   w2+s2  在此之前的的w和为 X

    那么 w1+s1 在前则 最大PDV 为 P1=max(X-s1,X+w1-s2);

    如果 w2+s2 在前则 最大PDV 为 P2=max(X-s2,X+w2-s1);

    我们可以同时把X去掉 则

    P1=max( -s1,w1-s2);

    P2=max( -s2,w2-s1);

    再将所有值加上 s1+s2 则

    P1=max(s2,w1+s1);

    P2=max(s1,w2+s2);

    那么P2 和 P1 那个小呢

    因为有 w2+s2>w1+s2  且 w2+s2>=s2

    所有P2>P1

    所以我们要P1的值 也就是将和小的排在前面 如果相等 会发现顺序无关

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <algorithm>
    
    #define LL long long
    
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    using namespace std;
    
    const int INF=0x5fffffff;
    const int N=100005;
    struct node
    {
        int w,s;
    }mem[N];
    bool cmp(node x,node y)
    {
        return (x.w+x.s)<(y.w+y.s);
    }
    int main()
    {
        //freopen("data.txt","r",stdin);
        int n;
        while(scanf("%d",&n)!=EOF)
        {
            for(int i=1;i<=n;++i)
            {
                scanf("%d %d",&mem[i].w,&mem[i].s);
            }
            sort(mem+1,mem+1+n,cmp);
            mem[0].s=mem[0].w=0;
            LL ans=0;
            LL temp=0;
            for(int i=1;i<=n;++i)
            {
                temp=temp+mem[i-1].w+mem[i-1].s-mem[i].s;
                if(temp>ans)
                ans=temp;
            }
            cout<<ans<<endl;
        }
        return 0;
    }
    
    
  • 相关阅读:
    第二次作业
    第五次作业
    第四次作业
    第三次作业
    第二次作业
    第三次作业
    第二次作业
    第二次作业
    gravity
    card
  • 原文地址:https://www.cnblogs.com/liulangye/p/2689062.html
Copyright © 2011-2022 走看看