Codeforces Round #812 (Div. 2) B Optimal Reduction

Problem - B - Codeforces

题意:

有一种操作:你可以选定一个区间,并把这个区间中所有的数都减1

给你一个数列a,数列a会有多种排列,问你当前给你的这种排列是不是这么多种排列中把所有的元素都变为0的最少操作数的排列

思路:

看到题,第一件事就是判断这属于什么题,这是贪心+操作

对于操作题,我们先直观想象一下该操作

然后我们去样例观察该操作具有一些什么性质,或者手写模拟一下

在观察操作有什么性质时,我们关注的是和问题有关的性质

我们关注的是操作次数,当区间[l,r]中间存在0元素时,就不能在这个区间内整体操作了,就只能分成两段区间操作了

当区间中间不会先比两边先出现0时,我们把操作区间慢慢往中间移动,这样操作次数就是\underset{l<=i<=r}{max}a[i]

但是如果中间先出现0时,操作次数就是\underset{l<=i<=m-1}{max}a[i]+\underset{m+1<=i<=r}{max}a[i]

因为中间那个先变为0的元素不会是\underset{l<=i<=r}{max}a[i]

所以

\underset{l<=i<=m-1}{max}a[i]+\underset{m+1<=i<=r}{max}a[i]>=\underset{l<=i<=r}{max}a[i]

因此当区间中间先变为0,贡献只会增加不会减少(贪心的思想

因此这个就是操作的性质

因此不能让中间先变成0

所以中间应该比两边大,即这应该是一个单峰函数

Code:

void solve(){
    int n,ok=1,flag=1;
    int a[mxn];
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    for(int i=1;i<=n-1;i++){
        if(a[i]>a[i+1]) flag=0;
        if(!flag&&a[i]<a[i+1]) ok=0; 
    }
    if(!ok) puts("NO");
    else puts("YES");
}

总结:

看到题,先判断这是什么题,再去确定思考方向,否则思路太乱了

对于操作题,我们

1.先直观想象一下该操作

2.然后我们去样例观察该操作具有一些什么性质,或者手写模拟一下

3.在观察操作有什么性质时,我们关注的是和问题有关的性质

当然要是想不出来看样例猜也是一种好办法,比如这道就能猜出来!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值