hdu4296 Buildings(贪心)

除夕夜刷题,好没效率。。。

还是没搞懂为何排序函数是按a.w + a.s < b.w + b.s。。。

不过尽力了,总比不看强吧。。。

-----------------------------------分割线-----------------------------------------------------

第二天想通了。。。

所谓的PDV,就是潜在损坏值(Potential Damage Value),每块板的PDV = 该板上面所有板(不包括本板)的重量 - 本板的强度。PDV越大,越容易损坏,是不是物理上很容易想通呀~。则一堆板的PDV = 该堆板中最大的PDV,直观理解就是干掉了这块板就破坏了整个堆的木板。

假设只有两块板,a和b,很显然下面的比上面的容易损坏,所以下面的PDV大。假设a在上面,其PDV值 = pdvb = wa - sb。假设b在上面,其PDV值 = pdva = wb - sa。然后两个值取最小,若a在上面的PDV小,则 wa - sb < wb - sa,即wa + sa < wb + sb。同理,若b在上面的PDV小,则wb + sb < wa + sa。上述并不是想得出递推公式,而是想说明w和s之间的关系是加减的关系。脑洞再进一步大一点,我们应该把越重强度越大的木板放在最下面,如此推出应该按照重量强度和从小到大排序然后处理的方案。

网上看了好多方法,个人认为他们的公式推理不严谨,但我也退不出严谨的公式,所以只能这样想了。

贪心任重而道远啊。。。

#include <stdio.h>
#include <string.h>
#include <cstdio>
#include<cstring>
#include <algorithm>

using namespace std;

const int N = 100005;
const int INF = 1<<27;

struct FLOOR
{
    int w;
    int s;
}flo[N];

bool cmp(const FLOOR &a,const FLOOR &b)
{
    return a.w + a.s < b.w + b.s;
}

int main()
{
  //  freopen("in.txt", "r", stdin);
    int n, i;
    __int64 maxx, sum;
    while(~scanf("%d", &n))
    {
        sum = 0;
        for(i = 0; i < n; i ++)
            scanf("%d%d", &flo[i].w, &flo[i].s);
        sort(flo, flo + n, cmp);
        maxx = sum = 0;
        for(i = 0; i < n; i ++)
        {
            maxx = max(maxx, sum - flo[i].s);
            sum += flo[i].w;
        }
        printf("%I64d\n", maxx);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值