poj3045 cow acrobats 贪心/邻项交换

题目链接:https://vjudge.net/problem/POJ-3045

题意:n个奶牛堆成一堆,每个都有重量和力气,奶牛i的危险值=i上方奶牛的总重量减去i的力气,求最大危险值的最小值。n<=50000

看到进阶指南上写了个邻项交换,大概就知道怎么想了。考虑两头奶牛p和q(其实就是比较函数cmp的写法):

1)若a[p].w>=a[q].w且a[p].s>=a[q].s,将p堆到q下面,若a[p].w<=a[q].w且a[p].s<=a[q].s将p堆到q上面 2)其他情况,设上方奶牛的总重为c。若p在上q在下,p的危险值为c-a[p].s,q的危险值为c+a[p].w-a[q].s,令rp=max(-a[p].s,a[p].w-a[q].s),同理若q在上p在下,令rq=max(-a[q].s,a[q].s-a[p].s)。显然若rp<rq则把p放在上面,否则把q放在上面。

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 
 5 const int maxn=500+10;
 6 struct st{ int w,s;}a[maxn];
 7 int n,i,ans,sum;
 8 
 9 bool cmp(st p,st q){
10     if (p.w>=q.w&&p.s>=q.s) return true;
11     else if (p.w<=q.w&&p.s<=q.s) return false;
12     else{
13         int rp=max(-q.s,q.w-p.s);
14         int rq=max(-p.s,p.w-q.s);
15         return rp<rq;
16     } 
17 }
18 
19 int main(){
20     scanf("%d",&n);
21     for (i=1;i<=n;i++) scanf("%d%d",&a[i].w,&a[i].s);
22     sort(a+1,a+n+1,cmp);
23     for (i=2;i<=n;i++) sum+=a[i].w;
24     ans=-1e9;
25     for (i=1;i<=n-1;i++) {
26         ans=max(ans,sum-a[i].s);
27         sum-=a[i+1].w;
28     }
29     ans=max(ans,-a[n].s);
30     printf("%d\n",ans);
31     return 0;
32 }
poj3045

 

猜你喜欢

转载自www.cnblogs.com/edmunds/p/12945494.html