转载:原文
- 分析
贪心。设有两个相邻物体 a(wi,si) , b(wj,sj)。假设a在方案一中这个位置上方总w为sum,显然只有两种情况 ——a上b下或a下b上。讨论最优解:
(1)对于方案一,PDV(a)=sum-si,PDV(b)=sum+wi-sj;
(2) 对于方案二,PDV(a)=sum+wj-si,PDV(b)=sum-sj;
如果想要方案一更优的话,则要按照方案一的方式排序,则有PDV(b)<PDV(a)–> wi-si<wj-si ==——> == wi+si<wj+sj。即总和小的在上面。
选方案二同理。
//AC代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long
struct node{
ll w, s;
bool operator<(const node &o)const{
return w + s < o.w + o.s;
}
}no[100005];
int main()
{
int n,i;
while (cin>>n)
{
for (i = 0; i < n; i++)
{
scanf("%lld %lld", &no[i].w, &no[i].s);
}
sort(no,no+n);
ll sum = no[0].w,ans=0;
for (i = 1; i < n;sum+=no[i++].w){
ans = max(ans, sum - no[i].s);
}
if(ans<0)
ans = 0;
printf("%lld\n", ans);
}
return 0;
}
下面代码超时来着,后来把输入改成cin竟然就过了!
#include <bits/stdc++.h>
using namespace std;
struct node{
int w, s;
bool operator<(const node &o)const{
return w + s < o.w + o.s;
}
}no[100010];
int main()
{
int n;
while (scanf("%d", &n))
{
for (int i = 0; i < n;i++){
scanf("%d %d", &no[i].w, &no[i].s);
}
sort(no,no+n);
long long sum = 0, max = -1,value;
for (int i = 0; i < n;i++){
value = sum - no[i].s;
sum+=no[i].w;
if(max<value)
max = value;
}
if(max<0)
max = 0;
printf("%lld\n", max);
}
return 0;
}
/*
3
10 6
2 3
5 4
2
2 2
2 2
3
10 3
2 5
3 3
1
0
2
*/