linkkkkk
题意:
给出
n
,
k
n,k
n,k和数组
a
a
a,每次都可以选出若干个元素让他们的值变成
(
a
i
+
1
)
m
o
d
k
(a_i+1)\mod k
(ai+1)modk
问最少需要几次操作才能使得数组非递减
思路:
操作次数是有单调性的,比如当
x
x
x次可以成功的话,
x
+
1
x+1
x+1次也可以成功,最后一次可以调整最大或最小元素。考虑二分答案。
对于
c
h
e
c
k
check
check,贪心的考虑,如果
b
i
=
=
b
i
−
1
b_i==b_{i-1}
bi==bi−1,跳过;如果
b
i
>
b
i
−
1
b_i>b_{i-1}
bi>bi−1,已经满足要求了,为了有利于后面的操作,尽可能的让
b
i
=
b
i
−
1
b_i=b_{i-1}
bi=bi−1,所需要的操作次数为
b
[
i
−
1
]
+
k
−
b
[
i
]
b[i-1]+k-b[i]
b[i−1]+k−b[i];如果
b
i
<
b
i
−
1
b_i<b_{i-1}
bi<bi−1,那么
b
i
b_i
bi一定要增大,跟
b
i
−
1
b_{i-1}
bi−1相等就可以了,所需要的操作次数为
b
[
i
−
1
]
−
b
[
i
]
b[i-1]-b[i]
b[i−1]−b[i],如果
b
[
i
−
1
]
−
b
[
i
]
<
m
i
d
b[i-1]-b[i]<mid
b[i−1]−b[i]<mid的话说明次数是不可行的,直接返回
f
a
l
s
e
false
false。
代码:
#include<bits/stdc++.h>
using namespace std;
int n,k,a[300007],b[300007];
bool check(int mid){
for(int i=1;i<=n;i++) b[i]=a[i];
for(int i=1;i<=n;i++){
if(b[i]<b[i-1]){
if(b[i-1]-b[i]>mid) return 0;
b[i]=b[i-1];
}
else{
if(b[i-1]+k-b[i]<=mid) b[i]=b[i-1];
}
}
return 1;
}
int main(){
cin>>n>>k;
for(int i=1;i<=n;i++) cin>>a[i];
int l=0,r=k,ans;
while(l<=r){
int mid=(l+r)/2;
if(check(mid)) ans=mid,r=mid-1;
else l=mid+1;
}
cout<<ans<<endl;
return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)