牛客小白月赛 B-Gaming

B-Gaming_牛客小白月赛54 (nowcoder.com)

题意:

有n个区间,你每在数轴上覆盖一个区间,积分就加s[i],问你不让区间全部被覆盖的最大积分是多少

思路:

还原一下当时写这道题的思路:

最大,那就考虑贪心,先假设所有区间全部覆盖了(贪心极端情况),然后去看拿走哪个区间可以让一个位置空出来。哇了一发,后来发现可能要去掉的不只一个区间,我们要去掉的是最少覆盖的位置上面包含的所有区间,所以我就想维护包含这个最小覆盖点的所有区间,也就是这个区间内的最小覆盖值,维护区间最小我就糊上了线段树,把包含最少覆盖点的区间都去掉,剩下的区间积分加起来就是答案了,然后就哇了。。。。

我不懂为什么会哇。。。

正解应该是:

要使区间没有完全覆盖,我们要至少留出一个空位
至于留出哪个空位我们不知道
因此我们去枚举这个空位
把覆盖这个空位的区间的积分贡献都减掉
那么总积分减去这个积分贡献就是答案

这个空位的积分贡献用区间++就可以,也就是差分

看起来好像差不多,但是我的做法显然烦了很多,也很易错

我的做法维护了一些本来就不需要维护的一些东西,比如一个空位到底是由哪些区间覆盖的,这根本就不需要维护,我们需要维护的只是这个空位上有多少积分,因此只需要差分就可以了!

Code:

/*
要使区间没有完全覆盖,我们要至少留出一个空位
至于留出哪个空位我们不知道
因此我们去枚举这个空位
把覆盖这个空位的区间的积分贡献都减掉
那么总积分减去这个积分贡献就是答案
*/
#include <bits/stdc++.h>
using namespace std;
const int mxn=1e6+10;
#define int long long
int n,m,sum=0;
int l[mxn],r[mxn],s[mxn],d[mxn],mi=1e18;
signed main(){
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d%d%d",&l[i],&r[i],&s[i]);
        d[l[i]]+=s[i];d[r[i]+1]-=s[i];
        sum+=s[i];
    }
    for(int i=1;i<=m;i++){
        d[i]+=d[i-1];
        mi=min(mi,d[i]);
    }
    printf("%lld\n",sum-mi);
}

总结:

1.只维护需要维护的内容!很多时候做法比别人烦就是因为维护了一些根本不需要维护的东西,因此以后做题的时候发现要维护一些数据的时候要提醒自己这个数据真的需要维护吗?和答案无关就不要维护!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值