首页 > 学院 > 开发设计 > 正文

poj - 3262 贪心,从n=2时的特殊情况推出n>=2通解的思想

2019-11-10 21:54:52
字体:
来源:转载
供稿:网友

poj-3262

贪心 水题

n头牛,每头牛每分钟造成d的破坏,把它赶回牛栏需要t的时间 问按什么顺序去赶牛最终破坏最小

思路:先考虑两头牛的情况,t1,d1和t2,d2 先赶1,破坏:2*t1*d2,先赶2,破坏:2*t2*d1(农夫还要回来所以要乘以2) 所以只需要比较t1*d2和t2*d1的大小就可以判断赶的顺序 比较函数为bool cmp(P a, P b) {return a.t*b.d < b.t*a.t; }

当n>2的时候,这个函数也适用 试想如果赶牛的顺序中有两头牛的顺序不符合上面的方式,那么,我们只要将这两头牛的顺序调换过来,最后的破坏就会小一些,所以必须要所有牛的顺序都符合,最后结果才是最小

还做过另一题类似的,两组数字,每组n个,记作ai,bi 每次从两组数字中各选一个数字,将它们相乘,将所有结果相加,如何的到最大结果 思路也是从n=2的时候开始考虑, 结果是:a1*b1+a2*b2或a1*b2+a2*b1 只需要比较两者大小 将两者相减: a1*b1+a2*b2-a1*b2-a2*b1 = a1*(b1-b2) - a2*(b1-b2) = (a1-a2)*(b1-b2) 显然,要得到最大值,两组数字必须是相通的顺序,从小到大或者从大到小排序 同样的,可以推广到n>=2的时候

注意int会溢出,要用long long

#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>using namespace std;typedef long long ll;const int MAXN = 100000 + 100;int n;struct P {int t, d; };bool cmp(const P &a, const P &b){ return a.t*b.d < b.t*a.d;}P p[MAXN];int main(){ while(scanf("%d", &n) == 1) { ll d = 0; for(int i=0; i<n; i++) scanf("%d%d", &p[i].t, &p[i].d), d+= p[i].d; sort(p, p+n, cmp); ll ans = 0; for(int i=0; i<n; i++) { d-=p[i].d; ans+=p[i].t*2*d; } cout << ans << endl; } return 0;}
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表