hdu4221

来源:互联网 发布:linux如何删vi除第一行 编辑:程序博客网 时间:2024/05/29 04:57
/*
分析:

    刚开始用的是反证法,反证法毕竟是猜答案然后证明它不错,既然想
到了正确的思路,那么反证法的就不啰嗦了,下面是我的思路,囧~~~


    假设存在一个序列(顺序任意),元素编号0~n-1,用base[i]表示0~i
所有元素的C[i]之和,取l>i,则有:
    ans[i]=base[i]-D[i];          (1)
    ans[l]=base[l]-D[l];           (2)
将i、l交换位置后,有:
    ans'[i]=base[l]-D[i];         (3)
    ans'[l]=base[i]-D[l];          (4)
取:
    max1=max((1),(3))=(3)=ans'[i];
    max2=max((2),(4))=(2)=ans[l];
则有:
    max1-max2=(base[l]-D[i])-(base[l]-D[l])=D[l]-D[i]。

用MAX表示4个式子的最大值:
    <1>当D[l]>D[i]时:
        MAX=max1,既MAX出现在了i、l交换位置后,让i在l后面的情况。
    (1)、(2)式子属于一种现实,(3)、(4)式子属于另一种现实,“我们
    需要做的是,使现实存在的情况中的max尽量小,所以我们要干掉i、
    l交换位置的情况,把等于max1的MAX消灭掉”,既:
        “当D[l]>D[i]时,不让i、l交换位置,不让i在l后面,既让i在
    l前面”
    <2>对于D[l]<D[i]的情况,同理。

    推理结束。
    所以按照上面的思想,将所有元素的完成时间按照从小到
大排序后,逐步计算即可。

                                                            2012-11-09
*/












#include"stdio.h"#include"string.h"#include"stdlib.h"struct A{int c,d;}E[100011];int n;int cmp(const void *a,const void *b){struct A *c,*d;c=(struct A *)a;d=(struct A *)b;return c->d-d->d;}int main(){int T,Case;int i;__int64 base;__int64 ans;scanf("%d",&T);for(Case=1;Case<=T;Case++){scanf("%d",&n);for(i=0;i<n;i++)scanf("%d%d",&E[i].c,&E[i].d);qsort(E,n,sizeof(E[0]),cmp);base=0;ans=0;__int64 temp;for(i=0;i<n;i++){temp=E[i].c+base-E[i].d;base+=E[i].c;if(temp>ans)ans=temp;}printf("Case %d: %I64d\n",Case,ans);}return 0;}


原创粉丝点击