power oj 3300【抢银行】dp+线段树

题目传送门:3300: 抢银行 -- Power OJ

样例输入:

3

1 0 0

2 0 1

3 1 1

样例输出:4

解题思路:

        题目很有意思,抛开抢劫的条件不谈,这题肯定就是一个贪心水题,但是因为有这个条件,反而有点无从下手,仔细想想,这题可以用dp来做,首先用一个结构体h[i]存储第i个银行对应的抢劫条件以及价值,用dp[i]表示的就是抢劫第i个银行所能得到的最大价值,那么我们的状态转移方程就能很容易的写出来:dp[i]=max(dp[h[i].l-h[i].r])+h[i].w;由于要遍历从h[i].l到h[i].r的dp值,出题者肯定会卡你这里的时间,笔者也是乱冲导致T2了,那么怎样优化呢,想到要求取区间内的最大值,那自然是线段树没跑了,开一个线段树,维护区间最大值,每次查询h[i].l到h[i].r的最大值后,将dp[i]算出来,接着更新线段树。遍历n次,答案就是dp[i]的max值,值得注意的这题的答案不是dp[n],它最大的时候万一不是抢第n个银行呢,对吧。

AC代码:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <map>
#include <unordered_map>
using namespace std;
#define LL long long
#define ll (now<<1|1)
#define rr ll+1
#define mid ((l+r)>>1)
const int N=2e5+10;
LL tree[4*N];
int n,a[N];
LL dp[N];
struct node{
    int l,r;
    LL w;
}h[N];
void update(int idx,LL val,int now=0,int l=0,int r=n)//区间查询
{
    if(idx<l||idx>r) return;
    if(idx==l&&l==r) tree[now]=val;
    else{
        update(idx, val,ll,l,mid);
        update(idx, val,rr,mid+1,r);
        tree[now]=max(tree[ll], tree[rr]);
    }
}
LL query(int idxl,int idxr,int now=0,int l=0,int r=n)//单点修改
{
    if(l>=idxl&&r<=idxr) return tree[now];
    else{
        if(idxr<=mid) return query(idxl, idxr,ll,l,mid);
        else if (idxl>mid) return query(idxl, idxr,rr,mid+1,r);
        return max(query(idxl, idxr,ll,l,mid), query(idxl, idxr,rr,mid+1,r));
    }
}
int main()
{
    scanf("%d",&n);
    for (int i=1; i<=n; i++) scanf("%lld%d%d",&h[i].w,&h[i].l,&h[i].r);
    for (int i=1; i<=n; i++) {
        dp[i]=query(h[i].l, h[i].r)+h[i].w;
        update(i, dp[i]);
    }
    LL ans=0;
    for (int i=1; i<=n; i++) {
        ans=max(ans, dp[i]);//获得答案
    }
    printf("%lld\n",ans);
    return 0;
}

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值