将n个数分为三部分,
则对这三个集合的数处理如下:
i. 中的元素,除去x和y的公倍数,全部都可以给朋友a
ii. 中的元素,除去x和y的公倍数,全部都可以给朋友b
iii. 中的元素,给朋友a或者朋友b都可以
不考虑两个人所需的cnt数,n个数中除去公倍数后满足条件:
将中的元素全部给a,则a还需个
将中的元素全部给b,则b还需个
则二者还需要的部分,从取即可
由于本题O(n)会超时,所以要用二分。
代码如下:
#include <cstdio>
#include <climits>
#define N INT_MAX
using namespace std;
int x, y, cnt_1, cnt_2, total, common;
inline bool is_ok(int num){
int exclu = num / common;
if((num - exclu) < total)
return false;
int t1 = num / y - exclu, t2 = num / x - exclu;
int rest1 = cnt_1 > t1 ? cnt_1 - t1 : 0;
int rest2 = cnt_2 > t2 ? cnt_2 - t2 : 0;
if(rest1 + rest2 <= num - num / x - num / y + exclu)
return true;
else
return false;
}
int main(){
scanf("%d %d %d %d", &cnt_1, &cnt_2, &x, &y);
total = cnt_1 + cnt_2;
common = x * y;
int l = total, r = N;
while(l < r){
int mid = l + ((r - l) >> 1);
if(is_ok(mid))
r = mid;
else
l = mid + 1;
}
printf("%d\n", l);
return 0;
}
小结:求最小值时,若能在O(n)内判断是否是一个可行解,就可以使用二分