codeforces 1443D Extreme Subtraction 贪心或差分

1443D Extreme Subtraction

题意:对于一个长度为n的数组有两种操作,前k个数减一,后k个数减一,这两种操作可执行任意多次,问是否能将数组变为全零
思路:首先的是暴力模拟,也可以叫做贪心吧,我们可以这样想尽可能的让左边减去更多,同时如果左边的减不掉那么多的话,用d来存储我们向右边借的数,如果a[i]-d小于零的话就意味着不能全变为零,反之,如果a[i]大于零且大于mm(mm为左边能提供的最大减数),那么这个时候就需要右边的帮忙,d要加上他们的差值,如果a[i]小于mm,那么就更新mm的值,因为之后左边能提供的最大减数变为了a[i]。

另外一种更为巧妙的是差分,首先获得该数组a的差分数组s,那么对于操作一,对数组s的操作变为s[0]–,s[k+1]++,对于操作二,对数组的操作变为s[k]–, s[n]++, (我的数组下标是0到n-1,1到n也行),那么就意味着现在能进行的操作是对这个数组大于零的数都能变为零,而小于零的数要进行判断如果所有小于零的数的和的绝对值小于等于s[0],即可以变为全零反之则不能。
代码如下:
差分

int a[maxn];
inline void cf(){
    int t=read();
    while(t--){
        int n = read(), res = 0;
        for(int i = 0; i < n; i++){
            a[i] = read();
            if(i&&a[i]<a[i-1]) res += a[i-1]-a[i];
        }
        if(res<=a[0]) printf("YES\n");
        else printf("NO\n");
    }
    return ;
}
signed main(){
    cf();
    return 0;
}

模拟部分代码如下:

int n = read();
for(int i = 0; i < n; i++) a[i] = read();
int flag = 1, d = 0, mm = a[0];
for(int i = 0; i < n; i++){
    a[i] -= d;
    if(a[i]<0){
        flag = 0;break;
    }
    if(a[i]>mm){
        d += a[i]-mm;
    }else mm = a[i];
}
if(flag) printf("YES\n");
else printf("NO\n");
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值