IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 二分、三分、01分数规划1 -> 正文阅读

[数据结构与算法]二分、三分、01分数规划1

例1

给一串n个单调递增的数,有q次询问>=x且<=y的数有多少个。

1<=n<=10^5;1<=q<=50000

认准一种算法,开始解释。解释详见代码,推荐在写代码时找例子试试,不用死记硬背。

为了防止l+r越界 ,可以写成这种形式:mid=l+(r-l)/2;

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=100, inf=0x7fffffff;
int a[maxn],n,l,r,x,y,mid,ansx,ansy;
int main(){
	cin>>n>>x>>y;
	for(int i=1;i<=n;++i)
		cin>>a[i];
	l=1; r=n;
	//>=x
	while(l<r){
		mid=l+(r-l)/2;//防止l+r越界 
		if(a[mid]>=x) r=mid;// 1 2 3,若要大于等于2而mid指向3,可能前面还有更好的答案
		else l=mid+1;//1 2 3,若要大于等于3而mid指向2,就要让l指向mid+1的位置 
	}
	ansx=r;
//	cout<<ansx<<endl;
	l=1; r=n;
	while(l<r){
		mid=l+(r-l)/2+1;//防止l不动 
		if(a[mid]<=y) l=mid;//0 1 2 3,若要小于等于2而mid指向1,可能后面还有更好的答案
		else r=mid-1; 
	}
	ansy=l;
//	cout<<ansy<<endl;
	cout<<ansy-ansx+1;//别忘了加一
	return 0;
} 

binary_search 返回bool,判断是否存在

lower_bound 返回可插入最小位置的迭代器(如lower_bound(a,a+3,4),其中a为{1,3,3},则返回可以插入3的迭代器位置:1之后)即查找第一个大于或等于num的数字。

upper_bound?返回可插入最大位置的迭代器(如lower_bound(a,a+3,4),其中a为{1,3,3},则返回可以插入3的迭代器位置:最后一个3之后)即第一个大于num的数字。

另外,可在从大到小的排序数组中,重载lower_bound()和upper_bound():

lower_bound( begin,end,num,greater<type>() ):查找第一个小于或等于num的数字,找到返回该数字的地址,不存在则返回end。

upper_bound( begin,end,num,greater<type>() ):从数组的begin位置到end-1位置二分查找第一个小于num的数字,找到返回该数字的地址,不存在则返回end。

所以上述问题直接用lower_bound-upper_bound就可以得出结果QAQ

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100, inf=0x7fffffff;
int a[maxn],n,l,r,x,y;
int main(){
	cin>>n>>x>>y;
	for(int i=1;i<=n;++i)
		cin>>a[i];
	cout<<lower_bound(a+1,a+1+n,x)-a<<endl;
	cout<<upper_bound(a+1,a+1+n,y)-a<<endl;
	cout<<upper_bound(a+1,a+1+n,y)-lower_bound(a+1,a+1+n,x);
	return 0;
} 

既然有了函数,啥时候用手写的呢?答案为:二分答案+检验

牛棚

有n个牛棚在x轴上,已知坐标,FJ有C只奶牛,每只必须安排在一个牛棚里,一个牛棚只能容纳一只,但它们会互相攻击,所以要求距离最近的两个牛棚间的距离最大。

2<=n<=100,000

0<=xi<=1,000,000,000

2<=C<=n

利用了二分的思想:通过结果反馈调整答案。在此题中,需要先对枚举出的答案进行试验,如果成功就再试一个更大的答案。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn=100005, inf=0x7fffffff;
int n,c,ans,a[maxn];
int main(){
	cin>>n>>c;
	for(int i=0;i<n;++i)
		scanf("%d",&a[i]);
	sort(a,a+n);
	int mid=1;
	while(1){
		int tot=1, now=a[0];
		for(int i=1;i<n;++i){
			if(a[i]>=now+mid){
				tot++, now+=mid;
				if(tot==c) break;
			}
		}
		if(tot==c){
			ans=tot;
			mid+=1;
			continue;
		}else break;
	}
	cout<<ans;
	
	return 0;
}

3104 -- Drying

刚洗过的衣服有n件。他们每个人在洗涤过程中都有一定水分每分钟,每件东西所含的水量都会减少1(当然,只有在东西还没有完全干燥的情况下)。当所含的水量变为零时,布会变干并准备好进行包装。

简每分钟都可以选择一件东西在散热器上晾干。散热器非常热,所以这个东西中的水量在这一分钟减少了k(但不小于零——如果这个东西含有少于k的水,那么产生的水量将是零)。

任务是通过有效地使用散热器来最大限度地减少干燥的总时间。当所有衣服都干燥时,干燥过程结束。

1<=n<=100 000? ;1<=a<=10^9? ;1<=k<=10^9

和上一道题类似,二分答案。关键在于如何判断x分钟能否晾干所有衣服。若x分钟可以自然风干,则不管它;若不能,则计算所需吹风机的时间,再与答案进行对比看吹风机时间够不够。

细节问题:

1、实际上当判断需要的吹风机时间时,需要减掉自然风干的时间!另外,还需要转换成double再用ceil上取整。

2、遇到sum这种求和的,应习惯性地检查是否会爆!

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=100005, inf=0x7fffffff;
int n,k,l=1,r,ans,a[maxn];
int jg(int x){
	long long sum=0;// 注意数据范围会爆int! 
	for(int i=0;i<n;++i){
		if(a[i]>x) 
			sum+=(int)(ceil((a[i]-x)*1.0/(k-1)));
	}
	return sum<=x;
}
int main(){
	scanf("%d",&n);
	for(int i=0;i<n;++i){
		scanf("%d",&a[i]);
		r=max(r,a[i]);
	}
	scanf("%d",&k);
	if(k==1){
		printf("%d",r);
		return 0;
	}
	while(l<=r){
		int mid=(l+r)>>1;
		if(jg(mid)) //若给的时间够了,说明最后找到的答案应该在r的后一个 
			r=mid-1;
		else
			l=mid+1; 
	}
	
	printf("%d",r+1);
	return 0;
}

总结

若出现解决最大或最小值问题,依次考虑:二分、贪心和动态规划。

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-03-06 13:22:01  更:2022-03-06 13:27:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 13:37:05-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码