Yuilice的题解
2024-06-11 20:47:48
发布于:浙江
21阅读
0回复
0点赞
题目大意
给出个元素,每个元素有两个属性,分别代表增加减少的闸值和增减数量。
你可以选定一个数字作为每一个元素的闸值,假如,那么你将获得点价值,否则减少价值。
求出总价值的最小取值。
思路分析
找单调性,很快可以发现是与成正比关系的,的数值越大,那么的数值也会相应的变大。
那么就可以针对于来进行二分,使得的同时,让的数值尽可能地小,针对于的区间来进行不停进行范围的枚举,直到满足要求为止。
可能会出现两种情况
- :此时说明的数值不足以达到目标,让变大即可。
- : 此时说明的数值已经达到目标,但是不一定是最小值,可能是之一,那么保存S继续缩短范围。
总计两步
- 使用二分得出合理的 ,时间复杂度为
- 使用枚举遍历求得,时间复杂度为
时间复杂度分析
代码示范
#include<bits/stdc++.h>
using namespace std;
long long n,m;
struct Node{
long long w,v;
}a[2000005];
bool check(long long x){
long long sum = 0;
for(int i = 1 ; i <= n ; i ++ ){
if(a[i].w <= x){
sum += x / a[i].w * a[i].v;
}else {
sum -= a[i].v;
}
}
return sum >= m;
}
int main()
{
cin >> n >> m ;
for(int i = 1 ; i <= n ; i ++ ){
cin >> a[i].w;
}
for(int i = 1 ; i <= n ; i ++ )
{
cin >> a[i].v;
}
long long left,right,answer;
left = 0;
right = 1e9+7;
answer = 0;
while(left <= right){
long long mid = left + right >> 1;
if(check(mid)){
answer = mid;
right = mid - 1;
}else {
left = mid + 1;
}
}
cout << answer << endl;
return 0;
}
—— Yuilice
全部评论 1
好好好
2024-06-13 来自 浙江
0
有帮助,赞一个