洛谷 P14115:[IAMOI R4] 木桶效应 ← 二分
【题目来源】
https://www.luogu.com.cn/problem/P14115
【题目描述】
小 t 有一个由 n 块竖直木板构成的木桶,第 i 块木板的高度为 ai。为了提升木桶的承水能力,她打算在木桶上加装一些木板。
小 t 有两种规格的木板,高度分别为 1 和 h,每种木板分别有 m 和 k 块。每块木板可以加装在木桶的一块木板的上方,此后原木板与加装的木板视为同一块木板。每块木板上可以加装多块木板。
由于承水能力只与最低的木板有关,所以小 t 想知道,在加装木板后,最低的木板高度最高能是多少。
【输入格式】
第一行包含四个整数 n,m,k,h。
第二行包含 n 个正整数 a1∼an,表示木板的高度。
【输出格式】
输出一行包含一个正整数,表示答案。
【输入样例1】
3 5 1 3
2 5 4
【输出样例1】
6
【输入样例2】
4 10 2 5
10 11 12 13
【输出样例2】
16
【输入样例3】
5 10 0 100
1 2 3 4 5
【输出样例3】
5
【样例1解释】
可以将 4 块高度为 1 的木板加装在第一块木板上,将 1 块高度为 1 的木板加装在第二块木板上,将 1 块高度为 3 的木板加装在第三块木板上,此时三块木板的高度分别为 6,6,7,高度最低的木板的高度为 6。
【数据范围】
对于所有数据,保证:1≤n≤10^5,0≤m,k≤10^9,1≤ai≤10^9,2≤h≤10^9。
【算法分析】
下面代码在洛谷上测试,仅仅得 50 分,没有得到 100 分。
择机再进行修改完善吧,O(∩_∩)O哈哈~。
【算法代码:50分代码】
#include <bits/stdc++.h>
using namespace std;typedef long long LL;
vector<LL> v;
LL n,m,k,h;bool check(LL target) {LL used_m=0,used_k=0;for(LL height:v) {if(height>=target) continue;LL diff=target-height;LL possible_k=(diff+h-1)/h;LL actual_k=min(possible_k,k-used_k);used_k+=actual_k;diff-=actual_k*h;if(diff>0) {used_m+=diff;if(used_m>m) return false;}}return true;
}int main() {cin>>n>>m>>k>>h;v.resize(n);for(LL i=0; i<n; i++) cin>>v[i];LL minh=v[0];for(LL i=1; i<v.size(); i++) {if(v[i]<minh) minh=v[i];}LL low=minh,high=minh+m+k*h;LL ans=minh;while(low<=high) {LL mid=low+(high-low)/2;if(check(mid)) {ans=mid;low=mid+1;} else high=mid-1;}cout<<ans<<endl;return 0;
}/*
in 1:
3 5 1 3
2 5 4out 1:
6in 2:
4 10 2 5
10 11 12 13out 2:
16in 3:
5 10 0 100
1 2 3 4 5out 3:
5
*/
【参考文献】
https://blog.csdn.net/hnjzsyjyj/article/details/148459348
https://blog.csdn.net/hnjzsyjyj/article/details/148715547