题意
t t t 组数据。
每一组数据中有 n , k n,k n,k 和一个数组 a a a。
有 k k k 次操作,每次操作可以使 a i + 1 a_{i} + 1 ai+1, i i i 满足 1 ≤ i ≤ n 1 \le i \le n 1≤i≤n 且 a i ≤ a i + 1 a_{i} \le a_{i + 1} ai≤ai+1。
思路
我们可以用二分答案来做。
因为结果最大是 2 × 1 0 8 2 \times 10^8 2×108,最小值是 a m a x a_{max} amax,对结果进行二分。
来看一下 c h e c k check check 咋写。
先枚举最大值的位置,若这个位置的值操作后能达到 m i d mid mid 的话,那么 a i − 1 a_{i - 1} ai−1 的值至少为 m i d − 1 mid - 1 mid−1,之后的值也可以递推出来。
代码
#include<bits/stdc++.h>
#define int long long
#define il inline
#define rg register
#define IOS ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
using namespace std;
int t,n,k,a[1005];
bool check(int x) {
for(rg int i(1); i <= n; ++i) {
int pos = k,flag = 0;
pos -= x - a[i];
if(pos < 0){
continue;
}
for(rg int j(i + 1); j <= n; ++j) {
if(a[j] < x + i - j){
pos -= x - j + i - a[j];
if(pos < 0) break;
}
else{
flag = 1;
}
}
if(flag) return 1;
}
return 0;
}
signed main() {
IOS;
cin>>t;
while(t--) {
int maxx = 0,ans = 0;
cin>>n>>k;
for(rg int i(1); i <= n; ++i) {
cin>>a[i];
maxx = max(maxx,a[i]);
}
int l = maxx,r = 2e8;
ans = maxx;
while(l <= r) {
int mid = (l + r) >> 1;
if(check(mid)) {
ans = mid;
l = mid + 1;
} else {
r = mid - 1;
}
}
cout<<ans<<endl;
}
return 0;
}
转载自洛谷