二分+贪心:最大化最小值+最小化最大值

最大化最小值:
Problem Description
Farmer John has built a new long barn, with N (2 <= N <= 100,000) stalls. The stalls are located along a straight line at positions x1,…,xN (0 <= xi <= 1,000,000,000). His C (2 <= C <= N) cows don’t like this barn layout and become aggressive towards each other once put into a stall. To prevent the cows from hurting each other, FJ want to assign the cows to the stalls, such that the minimum distance between any two of them is as large as possible. What is the largest minimum distance?

Input
Line 1: Two space-separated integers: N and C< br>< br>* Lines 2…N+1: Line i+1 contains an integer stall location, xi

Output
Line 1: One integer: the largest minimum distance

Sample Input
5 3
1
2
8
4
9

题目大意,求c个牛,n个摊位拜访的最小距离的最大值。
思路:二分+贪心。转换成判定问题,判断距离为distance,m头牛放n个位置能否放下,然后对distance进行二分。

#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;

int a[100000+10];

bool judge(int m, int n, int distance){		//判断距离为distance,m头牛放n个位置能否放下
	int current = a[0];	//当前放的牛的位置
	int num = 1;	//放了几头牛
	for(int i = 0;i < n; i++){
		if (a[i] - current >= distance){	//如果这个位置大于distance,就在这里放一头牛
			current = a[i];		//在a[i]处放一头牛
			num++;	
		}
	}
	if(num >= m)	//>=m,说明所有的牛都能放下
		return true;
	else
		return false;
}

int main(){
	int n, c;
	cin >> n >> c;
	for(int i = 0; i < n; i++){
		cin >> a[i]; 
	}
	sort(a,a + n);
	int left = 1;
	int right = a[n-1] - a[0];
	int mid;
	while (left <= right){	//二分法查找最小距离的最大值
		 mid = left + (right - left) / 2;
		if(judge(c, n, mid))
			left = mid + 1;
		else
			right = mid - 1;
	}
	cout << mid <<endl;
	system ("pause");
	return 0;
}

最小化最大值:
题目描述:
现有n件衣服需要烘干,每件衣服的含水量为ai如果自然晾干,每分钟含水量减少1。如果使用烘干机烘干,每分钟含水量减少k(直至为0)。只有一台烘干机,每次只能烘干一件衣服,且一次至少使用1分钟求使所有衣服含水量为0的最少时间是多少。

输入∶
第一行包含一个数字n(1<= n<= 105).示本服的数量。第二行有n个数,分别表示各件衣服的含水量ai(1<= ai <= 10个9),第三行一个整数k(1<= ai <= 10个9),表示烘干机一分钟能够减少的含水量。

输出:
输出一个整数,表示烘干衣服所需的最小时间。样例输入:
3
2 3 9
5

样例输出:
3

思路:二分加贪心,转换为判定性问题,判断t时间是否可行,再对t进行二分。

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<math.h>
using namespace std;

int  water[10000 + 10];

bool judge(int n, int k, int t){
	int sum = 0;
	for(int i = 0;i < n; i++){
		if(water[i] > t){
			sum +=  ceil(1.0 * water[i] / (k-1));//向上取整
		}
	}
	if(sum > t)
		return false;
	else
		return true;
}

int main(){
	int n, k;
	cin >> n;
	for(int i = 0; i < n; i++){
		cin >> water[i];
	}
	sort (water, water + n);
	cin >> k;
	if(k == 1){		//如果烘干速度和自然晾干一样,则返回最湿的衣服所需的晾干时间
		cout << water[n - 1] << endl;
	}else{
		int left = 1;
		int right = water[n - 1];
		int mid;
		while(left <= right){
			mid = left + (right - left) / 2;
			if(judge(n, k, mid)){
				right = mid - 1;
			}
			else{
				left = mid + 1;
			}
		}
		cout << mid << endl;
	}
	system("pause");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值