zoukankan      html  css  js  c++  java
  • surf(树状数组+DP)

    题意:

    给出一些事件的开始时间和持续时间,你必须在开始时间前做这件事,做完才能做别的,每件事有固定的报酬,询问怎么安排报酬最大。

    题解:

    可以写出DP方程:

    这里的mmax表示这个事件开始时间之前所能达到的最大报酬。

    dp[ed]=max(dp[ed],mmax+Node[i].w);

    然后从1到N做一遍DP即可,这里前缀最大值需要用一个树状数组维护,但是不用好像也能过。。。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=3e6+100;
    struct node {
        ll st;
        ll ed;
        ll w;
    }Node[maxn];
    ll dp[maxn];
    ll c[maxn];
    ll E=0;
    int cmp (node a,node b) {
        if (a.st!=b.st) return a.st<b.st;
        else return a.ed<b.ed;
    }
    int lowbit (int x) {
        return x&-x;
    }
    ll getsum (int x) {
        ll ans=0;
        for (int i=x;i;i-=lowbit(i)) ans=max(ans,c[i]);
        return ans;
    }
    void update (int t,ll x) {
        for (int i=t;i<=E;i+=lowbit(i)) c[i]=max(c[i],x);
    }
    int main () {
        int N;
        scanf("%d",&N);
        for (int i=1;i<=N;i++) {
            ll x;
            scanf("%lld%lld%lld",&Node[i].st,&Node[i].w,&x);
            Node[i].ed=Node[i].st+x;
            E=max(E,Node[i].ed);
        }
        sort(Node+1,Node+1+N,cmp);
        for (int i=1;i<=N;i++) {
            ll st=Node[i].st;
            ll ed=Node[i].ed;
            ll mmax=getsum(st);
            dp[ed]=max(dp[ed],mmax+Node[i].w);
            update(ed,dp[ed]);
        }
        ll Max=0;
        for (int i=0;i<=E;i++) Max=max(Max,dp[i]);
        printf("%lld
    ",Max);
    }
  • 相关阅读:
    第六章
    第七章
    第五章
    第四章
    第三章
    第二章
    第一章
    Android深度探索——第十章读书笔记及心得
    Android深度探索——第九章读书笔记及心得
    Android深度探索——第八章读书笔记及心得
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/12898133.html
Copyright © 2011-2022 走看看