zoukankan      html  css  js  c++  java
  • NYOJ 720 DP+二分

    项目安排

    时间限制:3000 ms  |  内存限制:65535 KB
    难度:4
    描述
    小明每天都在开源社区上做项目,假设每天他都有很多项目可以选,其中每个项目都有一个开始时间和截止时间,假设做完每个项目后,拿到报酬都是不同的。由于小明马上就要硕士毕业了,面临着买房、买车、给女友买各种包包的鸭梨,但是他的钱包却空空如也,他需要足够的money来充实钱包。万能的网友麻烦你来帮帮小明,如何在最短时间内安排自己手中的项目才能保证赚钱最多(注意:做项目的时候,项目不能并行,即两个项目之间不能有时间重叠,但是一个项目刚结束,就可以立即做另一个项目,即项目起止时间点可以重叠)。
    输入
    输入可能包含多个测试样例。
    对于每个测试案例,输入的第一行是一个整数n(1<=n<=5000):代表小明手中的项目个数。
    接下来共有n行,每行有3个整数st、ed、val,分别表示项目的开始、截至时间和项目的报酬,相邻两数之间用空格隔开。
    st、ed、value取值均在32位有符号整数(int)的范围内,输入数据保证所有数据的value总和也在int范围内。
    输出
    对应每个测试案例,输出小明可以获得的最大报酬。
    样例输入
    3
    1 3 6
    4 8 9
    2 5 16
    4
    1 14 10
    5 20 15
    15 20 8
    18 22 12
    样例输出
    16
    22
    提示
    上传时数据加强,项目起始时间和终止时间可能相同(其他oj可能无此情况)
    来源
    网易有道2013年校园招聘面试二面试题
    上传者
    勿念情
    感觉N^2也可以过啊,T了,后来用的二分A掉,二分写炸了调了半天最后发现排序小标写错了,ccc
    dp[i]表示前i个项目可获得的最大价值,则dp[i]=max(dp[i-1],solve(i-1)+P[i].val)
    solve()就是我们要找的在满足与目标项目不交叉的情况下的最大价值。
    由于要二分查找显然dp[]数组必须有序,所以dp[i]表示前i个项目可获得的最大价值,这样的话二分找到的某个合法项目之前的项目显然也在目标项目之前且不交叉。
    #include<bits/stdc++.h>
    using namespace std;
    #define inf 0x3f3f3f3f;
    struct node
    {
        int st,ed,val;
        bool operator<(const node &c)const{
        if(st==c.st&&ed==c.ed) return val>c.val;
        if(ed==c.ed) return st<c.st;
        return ed<c.ed;
        }
    }P[5005];
    int dp[5005];
    int solve(int t)
    {
        if(!t) return 0;
        int l=1,r=t,mid,i,j,k,ans=0;
        while(l<r){
            mid=r-(r-l)/2;
            if(P[mid].ed<=P[t+1].st){
              l=mid;
            }
            else{
              r=mid-1;
            }
        }
        if(l==r&&P[l].ed<=P[t+1].st) return dp[l];
        return 0;

    }
    int main()
    {
        int N,i,j,k;
        node a,b;
        while(cin>>N){
            for(i=1;i<=N;++i){
                scanf("%d%d%d",&P[i].st,&P[i].ed,&P[i].val);
            }
            sort(P+1,P+N+1);
        for(i=1;i<=N;++i){
            dp[i]=max(solve(i-1)+P[i].val,dp[i-1]);
        }
        printf("%d ",dp[N]);
        }
        return 0;
    }

  • 相关阅读:
    java课后作业-4
    课堂练习
    16年9月27日上午
    《大道至简》第二章读后感
    《大道至简》-编程的精义读后感
    用Windbg来看看CLR的JIT是什么时候发生的
    如何调试什么时候SaveFileDialog会被Dispose
    针对C#程序做性能测试的一些基本准则
    要注意null合并运算符的优先级比+还要低
    实现GetHashCode时要遵循的规则
  • 原文地址:https://www.cnblogs.com/zzqc/p/7102863.html
Copyright © 2011-2022 走看看