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

最大化最小值:
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;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【资源说明】 python基于贪心、迭代实现的生物遗传物质切割算法源码.zip 该项目是个人毕设项目源码,评审分达到95分,都经过严格调试,确保可以运行!放心下载使用。 该项目资源主要针对计算机、自动化等相关专业的学生或从业者下载使用,也可作为期末课程设计、课程大作业、毕业设计等。 具有较高的学习借鉴价值!基础能力强的可以在此基础上修改调整,以实现类似其他功能。 本项目实现将一个基因片段进行剪切,基因片段长度通常为500bp左右 实现步骤: 1. 使用贪心算法得到初始剪切位点 2. 从左往右,对上一步得初始切割得到的片段进行左右移动,实际上就是对每一个基因片段的切割位点进行左右移动 3. 使用贪心算法 变量: 1. 每个基因片段的最小长度和最大长度 2. 剪切后每个基因片段的最小值最大值 3. 每个剪切基因片段之间的距离最大值最小值可能为0,会不会有问题 4. 第一步贪心算法保存几个结果(10个 5. 每条链开头和结束最多可以剪切多少 #### 尝试更改 1. 使用整条gene的tm当做开始(不行,tm与第一次切割得到的tm相差太大) * 当前使用直接使用第一个与第二个最接近的当做开始,然后使用第一次切割得到的均值当做第二次切割的开始 2. 从后面开始或者从中间开始,得到多个切割的结果提供选择 * 或者使用第一步得到的tm序列中选择tm最小值的中间开始 3. 将每个片段输出 4. 将剪切后的结果进行拼接,得到有gap形式的链 5. 尝试根据第一遍遍历得到的序列tm分布情况得到从中间开始切割的位点 6. 程序中在迭代过程中好像还存在第一个切割位点(0)点不会向右移动的问题 #### 展示 1. 每个gap长度 2. 序列长度 #### 问题 1. 存在某些gap长度为0,会不会使得发卡结构概率变大?(没问题) 2. 第二条链得到的是3'端到5'端还是(第一条和第二条(互补链))--解决 3. C(1/n)没做,体现在C(2/n),一条链自成环可以体现在两条相同的链形成的发卡结构 4. primer浓度偏大影响大不大,(可能在nupack包中计算影响不大) 5. 输出什么(切割得到的片段、拼接后得到的片段、切割位点、解链温度、片段长度、 6. 输入什么(各种离子的浓度、切割允许的最大长度和最小长度、温度 --- 钠离子浓度默认为1mol/L over_lap开始不能取对tm标准差影响最大的,应该直接用tm最大上的 over_lap过程最多截取多少,两个小片段之间最大是多少 为了不影响两个片段之间,现在只是对每个片段处理 最后一段不够最小长度不管他 ------------------- 迭代: 每个片段长度最小为: min_len-5 每个片段长度最大值: max_len+5 -------------------- 细节问题: 1. 默认输入是5'端到3'端,返回的结果上面的单链是5'端到3'端,下面的是?(5'端到3'端,还是3'端到5'端)

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值