除夕夜刷题,好没效率。。。
还是没搞懂为何排序函数是按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;
}