首页 > 代码库 > poj 3045
poj 3045
/* 题意: 给定n,然后是n头牛,每头牛有一个重量w,力量s 要求把n头牛一个叠在一个头上,类似叠罗汉 对于一个叠罗汉的序列,每头牛的risk是它顶上的牛的重量之和减去它的s 对于序列的最大的risk就是这个序列的risk 问如何确定一种序列使得risk最小 解析: 首先要想到,对于相邻的两头牛,交换它们的位置,仅仅会影响他们两个的risk值 然后,对于最优系列的相邻的两头牛 w1 s1 w2 s2 最顶上的那头的顶上的牛的质量和为sum 那么第一头牛的risk就是 sum - s1 r1 第二头的为sum + w1 - s2 r2 假如交换位置之后: sum - s2 r3 sum + w2 - s1 r4 有:max(r1,r2) < max(r3,r4)——r1..r4分别对应四个risk 那么,有四种假设: r1 < r3 r1 < r4 r2 < r3 r2 < r4 当然这四个假设,每一个都还隐含了两个不等式,在这里先不写出来 因为明显有 r1 < r4 r2 > r3 所以,只剩下: 1.r1 < r3 —— r1 > r2 && r3 > r4 2.r2 < r4 —— r2 > r1 && r4 > r3 对于1: s2 - s1 > w1 && s1 - s2 > w2,因为w1,w2都大于0,所以不符合。 所以只剩下2 得到:w1 + s1 < w2 + s2 综上,得出w+s最大的必定在最底下,按照w+s排序得到的就是最优序列。 顺便,要注意一下,risk是可以为负数的,所以初始化的时候不可以为0。*/#include <iostream>#include <cstdio>#include <algorithm>#define range(i,a,b) for (int i=a;i<=b;i++)const int maxn = 50000;typedef long long ll;using namespace std;struct Data{ ll w,s; friend bool operator < (const Data &a,const Data &b) { return a.w+a.s < b.w + b.s; }};ll n;Data dat[maxn+1];void input(ll &a){ scanf("%I64d",&a);}int main(){ input(n); range(c,1,n) { input(dat[c].w); input(dat[c].s); } sort(dat+1,dat+1+n); ll sum(0); ll risk=-(1<<29); //初始化状态为0的话,就会WA! range(i,1,n) { risk = sum - dat[i].s > risk ? sum - dat[i].s : risk; sum += dat[i].w; } cout<<risk<<endl; return 0;}
poj 3045
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。