zoukankan      html  css  js  c++  java
  • BZOJ2034 [2009国家集训队]最大收益

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作。

    本文作者:ljh2000
    作者博客:http://www.cnblogs.com/ljh2000-jump/
    转载请注明出处,侵权必究,保留最终解释权!

     

    Description

    给出N件单位时间任务,对于第i件任务,如果要完成该任务,需要占用[Si, Ti]间的某个时刻,且完成后会有Vi的收益。求最大收益。 N≤5000,1 ≤ Si ≤ Ti ≤ 108,1 ≤ Vi ≤ 108。 澄清:一个时刻只能做一件任务,做一个任务也只需要一个时刻。

    Input

    第一行一个整数N,表示可供选择的任务个数. 接下来的第二到第N+1行,每行三个数,其中第i+1行依次为Si,Ti,Vi

    Output

    输出最大收益

    Sample Input

    4
    1 1 2
    2 2 2
    1 2 3
    1 3 1

    Sample Output

    6

    HINT

     

    共有四个任务,其中第一个任务只能在时刻1完成,第二个任务只能在时刻2做,第三个任务只能在时刻1或时刻2做,第四个任务可以在[1,3]内任一时刻完成,四个任务的价值分别为2、2、3和1。一种完成方案是:时刻1完成第一个任务,时刻2完成第三个任务,时刻3完成第四个任务,这样得到的总收益为2+3+1=6,为最大值。

     

     

    正解:贪心

    解题报告:

      这题的思想和推导过程十分巧妙,贪心的运用让人不明觉厉...

      完整解题报告:http://wenku.baidu.com/link?url=YkUqLK3EDJlzsFdqQU1V5cOnFGS4lSwJNSRywEVImSJB9y-F6cStCd92uxHu_NzOJjQQKidR0f_T1S7-C3YjZWvym4NPwXLhMaub3GcWgge 。

      具体做法:

      首先按权值从大到小排序,然后依次选择区间,能选就选,论文中证明了这一做法的正确性。

      同时在check能否选取的时候,选取的方法是查看当前结点是否已经匹配,未匹配则直接选择,否则看一下已经匹配了的这个区间和当前区间那个的右端点更靠右,让更靠右的往右寻找可行的位置。

      这样做可以证明是对的(详见论文啦),同时复杂度是$O(n^2)$。

    //It is made by ljh2000
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    typedef long long LL;
    const int MAXN = 5011;
    LL ans;
    int n,pos[MAXN],belong[MAXN*2];
    struct seg{ int l,r,s,val; }a[MAXN];
    inline bool cmpx(seg q,seg qq){ return q.l<qq.l; }
    inline bool cmpz(seg q,seg qq){ return q.val>qq.val; }
    inline int getint(){
        int w=0,q=0; char c=getchar(); while((c<'0'||c>'9') && c!='-') c=getchar();
        if(c=='-') q=1,c=getchar(); while (c>='0'&&c<='9') w=w*10+c-'0',c=getchar(); return q?-w:w;
    }
    
    inline bool check(int k,int x){
    	if(pos[x]>a[k].r) return false;
    	if(!belong[x]) { belong[x]=k; return true; }
    	else {
    		if(a[belong[x]].r<a[k].r) return check(k,x+1);
    		else if(check(belong[x],x+1)){
    			belong[x]=k; return true;
    		}
    		return false;
    	}
    }
    
    inline void work(){
    	n=getint(); for(int i=1;i<=n;i++) a[i].l=getint(),a[i].r=getint(),a[i].val=getint();
    	sort(a+1,a+n+1,cmpx);
    	for(int i=1;i<=n;i++) pos[i]=max(pos[i-1]+1,a[i].l);
    	for(int i=1;i<=n;i++) {
    		a[i].s=a[i-1].s;
    		while(pos[a[i].s]<a[i].l && a[i].s<n) a[i].s++;
    	}
    	sort(a+1,a+n+1,cmpz);
    	for(int i=1;i<=n;i++) if(check(i,a[i].s)) ans+=a[i].val;
    	printf("%lld",ans);
    }
    
    int main()
    {
        work();
        return 0;
    }
    

      

  • 相关阅读:
    小白的进阶之路7
    小白的进阶之路6
    小白的进阶之路5
    小白的进阶之路4
    小白的进阶之路3
    小白的进阶之路2
    小白的进阶之路1
    02CSS布局13
    02css定位12
    02css盒子模型11
  • 原文地址:https://www.cnblogs.com/ljh2000-jump/p/6274851.html
Copyright © 2011-2022 走看看