[笔记][中国大学mooc][程序设计与算法(二) 算法基础][二分算法] 农夫和奶牛

本文主要是介绍[笔记][中国大学mooc][程序设计与算法(二) 算法基础][二分算法] 农夫和奶牛,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目

在这里插入图片描述

分析

本题的解空间是 [ 1 , ( 1 0 9 + 1 ) − 1 C − 1 ] ⋂ Z + [1,\frac{(10^9+1)-1}{C-1}]\bigcap{Z^+} [1,C1(109+1)1]Z+(这里老师在课上讲的区间是 [ 1 , 1 0 9 C ] [1,\frac{10^9}{C}] [1,C109],考虑有两头牛,牛舍在 0 0 0 1 0 9 10^9 109的位置都存在,那么这个最大距离就应当是 1 0 9 − 0 1 \frac{10^9-0}{1} 11090,所以这里可能有点问题,但是不影响老师所讲的二分法核心思想)另外,考虑到可以获取到最左边和左右边个隔间的位置,所以牛的最大间距就是 [ 1 , b i g g e s t P o s i t i o n − s m a l l e s t P o s i t i o n C − 1 ] ⋂ Z + [1,\frac{biggestPosition-smallest Position}{C-1}]\bigcap{Z^+} [1,C1biggestPositionsmallestPosition]Z+,解空间进一步缩小
本题即是在上述解空间中进行二分查找。

本题目与[笔记][中国大学mooc][程序设计与算法(二) 算法基础][二分算法] 派题目十分相似(核心都是二分法),但是本题目在验证某数是否属于解空间的时候,需要按顺序遍历整个隔间位置的序列。
而且本题目的解空间是离散的,在二分法中可能会出现很多问题:

  1. 递归函数必须强制收缩左右边界,意思是在验证了 ⌊ ( L + R ) 2 ⌋ \lfloor\frac{(L+R)}{2}\rfloor 2(L+R)的可行性后,如果可行需要将左边界收缩到 ⌊ ( L + R ) 2 ⌋ + 1 \lfloor\frac{(L+R)}{2}\rfloor+1 2(L+R)+1的位置,注意同时需要记住这个 ⌊ ( L + R ) 2 ⌋ \lfloor\frac{(L+R)}{2}\rfloor 2(L+R);否则将右边界收缩至 ⌊ ( L + R ) 2 ⌋ − 1 \lfloor\frac{(L+R)}{2}\rfloor-1 2(L+R)1。原因是如果解在 [ a , a + 1 ] [a,a+1] [a,a+1] ⌊ ( L + R ) 2 ⌋ = a \lfloor\frac{(L+R)}{2}\rfloor=a 2(L+R)=a,如果不主动收缩左边界,下一次调用区间是不会收缩的,产生死循环。
  2. 递归函数在 [ L , R ] [L,R] [L,R]中找不到解的情况(比如上一次调用递归函数的值已经是正确的了,如果继续验证是否有更大的解,就会发生找不到解的情况),所以需要先验证左边界 L L L是否在解空间内。

代码

#include<stdio.h>
#define MAXN 100000
long long N, C;//C=#cows N=#stalls
long long positionOfStalls[MAXN];
//判断该距离是否能把牛全部装下
bool IsCurrentDistanceWorks(long long testDistance){long long lastCowPosition = positionOfStalls[0];long long restCows = C-1;for(int cnt=0; cnt<N; cnt++){if(positionOfStalls[cnt]-lastCowPosition >= testDistance){restCows--;lastCowPosition = positionOfStalls[cnt];}if(restCows == 0)return true;}return false;
}
//找到[L,R]内的最大间隔
long long MinimizeLargestDistance(long long L, long long R){if(IsCurrentDistanceWorks(L)){if(L>=R)return L;}elsereturn 0;if(IsCurrentDistanceWorks((L+R)/2)){long long evenLargerDistance = MinimizeLargestDistance((L+R)/2+1, R);return evenLargerDistance > (L+R)/2 ? evenLargerDistance : (L+R)/2;}elsereturn MinimizeLargestDistance(L, (L+R)/2-1);
}
//归并排序
void Merge(long long ptr_head1, long long ptr_head2, long long ptr_tail){long long ptr1 = ptr_head1, ptr2 = ptr_head2, ptr=0;long long tempSquenceForMerge[ptr_tail-ptr_head1+1];while(ptr1<ptr_head2&&ptr2<=ptr_tail)tempSquenceForMerge[ptr++] = positionOfStalls[ptr1]<positionOfStalls[ptr2]?positionOfStalls[ptr1++]:positionOfStalls[ptr2++];while(ptr1<ptr_head2)tempSquenceForMerge[ptr++] = positionOfStalls[ptr1++];while(ptr2<=ptr_tail)tempSquenceForMerge[ptr++] = positionOfStalls[ptr2++];ptr=0;for(long long cnt=ptr_head1; cnt<=ptr_tail; cnt++)positionOfStalls[cnt]=tempSquenceForMerge[ptr++];
}
void MergeSort(long long ptr_head, long long ptr_tail){if(ptr_head >= ptr_tail) return;MergeSort(ptr_head, (ptr_head+ptr_tail)/2);MergeSort((ptr_head+ptr_tail)/2+1, ptr_tail);Merge(ptr_head, (ptr_head+ptr_tail)/2+1, ptr_tail);
}
//void QuickSort(long long ptr_head, long long ptr_tail){
//	if(ptr_head>=ptr_tail)
//		return;
//	long long ptr1 = ptr_head, ptr2 = ptr_tail;
//	long long timeOfExchanges = 0;
//	long long tempForExchange;
//	while(ptr1 < ptr2){
//		if(positionOfStalls[ptr1] > positionOfStalls[ptr2]){
//			tempForExchange = positionOfStalls[ptr1];
//			positionOfStalls[ptr1] = positionOfStalls[ptr2];
//			positionOfStalls[ptr2] = tempForExchange;
//			timeOfExchanges++;
//		}
//		if(timeOfExchanges%2)
//			ptr1++;
//		else
//			ptr2--;
//	}
//	QuickSort(ptr_head, ptr1-1);
//	QuickSort(ptr1+1, ptr_tail);
//}
int main(){freopen("in.txt", "r", stdin);scanf("%d %d", &N, &C);for(int cnt=0; cnt<N; cnt++)scanf("%d", positionOfStalls+cnt);MergeSort(0, N-1);printf("%d", MinimizeLargestDistance(1, (positionOfStalls[N-1]-positionOfStalls[0])/(C-1)));return 0;
} 

出现的问题

在第一次提交的时候,代码中使用的是快速排序,测试样例中有一个例子是77777个隔间位置,而隔间位置都是从小到大输入的。此时如果使用快速排序,理论上会产生77777次递归调用,这肯定会导致溢出。所以改用归并排序后,情况得以解决

这篇关于[笔记][中国大学mooc][程序设计与算法(二) 算法基础][二分算法] 农夫和奶牛的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/953609

相关文章

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que

hdu2289(简单二分)

虽说是简单二分,但是我还是wa死了  题意:已知圆台的体积,求高度 首先要知道圆台体积怎么求:设上下底的半径分别为r1,r2,高为h,V = PI*(r1*r1+r1*r2+r2*r2)*h/3 然后以h进行二分 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#includ

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

秋招最新大模型算法面试,熬夜都要肝完它

💥大家在面试大模型LLM这个板块的时候,不知道面试完会不会复盘、总结,做笔记的习惯,这份大模型算法岗面试八股笔记也帮助不少人拿到过offer ✨对于面试大模型算法工程师会有一定的帮助,都附有完整答案,熬夜也要看完,祝大家一臂之力 这份《大模型算法工程师面试题》已经上传CSDN,还有完整版的大模型 AI 学习资料,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费