GRH:【 我这么喜欢复用曾经题目 然后揉起来的人……你们居然还没套路起来 】
计网的烦恼(一维覆盖问题)
由题目我们可以知道,答案一定在[l,pl[n]−pl[1]+1][l,pl[n]−pl[1]+1]中,所以我们可以二分答案。
通过枚举每一个答案然后判断这个答案合不合理。
在这个题目中,如果我们发现答案可以cover所有的地方,那么我们就要去寻找更小的答案,如果发现无法cover,我们就去寻找更大的答案。
至于是否可以cover可以使用到贪心的思路,如果一个点无法被覆盖,那么就选取给定长度区间的左端点与该点重合进行覆盖。
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #define INF 0x3f3f3f3f #define eps 1e-8 #define MaxSize 100005 using namespace std; int n, m; int A[MaxSize], B[MaxSize]; bool judge(double t) { int temp = A[0]; int num = 1; for(int i = 1; i < n; i++){ if(A[i]-temp > t * 2) { ++num; temp = A[i]; } else continue; } if (num <= m) return false; else return true; } int main() { while (~scanf("%d %d", &m, &n)) { for (int i = 0; i < n; i++) { scanf("%d",&A[i]); } sort(A,A+n); double left = 0, right = 10000, mid, ans; while (right - left >= eps) { mid = (left + right) / 2.0; if (judge(mid)) { left = mid; } else{ right = mid; ans = mid; } } printf("%.1lf\n", ans); } }
1052: [HAOI2007]覆盖问题(二维覆盖问题)
1052: [HAOI2007]覆盖问题
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1540 Solved: 705
[Submit][Status][Discuss]
Description
Input
Output
一行,输出最小的L值。
Sample Input
0 1
0 -1
1 0
-1 0
Sample Output
HINT
100%的数据,N<=20000
Source
这道题总体的思路还是二分答案+贪心验证 只不过这道题是从一维推广到二维了而已。
题意:网格图,给出nn个点,要求用3个边长相同的正方形覆盖所有点,求最小边长.
如何贪心验证呢?我们注意到是3个正方形.为什么是3个?
我们先找出覆盖所有点的最小距形,那么距形的四条边必须有正方形贴着,而又是3个正方形,所以至少要有1个正方形同时贴着两条边.
1.贴着的边相对:这样的话三个正方形都同时贴着相对的两条边,比如是上下两条边,那么贴着左边的那个正方形就贴着3条边,在距形的一角.
2.贴着的边相邻:这样的话这个正方形就在距形的一角.
所以我们递归的把正方形放在距形的一角,然后去掉已经覆盖了的点,继续放正方形即可.(贪心的思路)
原题解博客(https://www.cnblogs.com/Sunnie69/p/5649055.html)
洛谷 P1824 进击的奶牛 【二分答案】(求最大的最小值)
题目描述
Farmer John建造了一个有N(2<=N<=100,000)个隔间的牛棚,这些隔间分布在一条直线上,坐标是x1,...,xN (0<=xi<=1,000,000,000)。
他的C(2<=C<=N)头牛不满于隔间的位置分布,它们为牛棚里其他的牛的存在而愤怒。为了防止牛之间的互相打斗,Farmer John想把这些牛安置在指定的隔间,所有牛中相邻两头的最近距离越大越好。那么,这个最大的最近距离是多少呢?
输入格式:
第1行:两个用空格隔开的数字N和C。
第2~N+1行:每行一个整数,表示每个隔间的坐标。
输出格式:
输出只有一行,即相邻两头牛最大的最近距离。
5 3 1 2 8 4 9
3
解题思路:
像这种求最大最小值,最小最大值得问题都是典型的二分答案题,二分答案的主要难点在于juge()函数,此题下面给出了两个不同思路的juge函数。
要注意的是如何根据所枚举的答案来将隔间分隔,因为求的是最大的最近距离,这个距离要是每一次分隔距离中最短的。接下来分析,假设隔间的坐标没有规定在哪的话,那么什么时候最近距离最大呢?毫无疑问,是当所有的距离
相同的时候,最近距离最大。但是此题每个隔间的坐标有规定,使得不一定能使每一段的距离都能够相等,所以,此时求最近距离的最优思路就是:
每一段区间距离都应该大于或等于m(但要尽可能的接近最近距离),这样才能使最近距离最大
所以一旦所枚举的隔间距离恰好大于最近距离的时候,就在该隔间放牛,毫无疑问,这样得到的最近距离才会尽可能的大
原博客链接(https://www.cnblogs.com/00isok/p/9063340.html)
洛谷OJ - P1316 - 丢瓶盖(二分答案)
二分法,终点在于写check函数,第一个瓶盖是必选的,之后贪心的选择第一个能让距离大于等于所check的答案,然后再以这个瓶盖继续贪心选择下一个。之后判断选择的瓶盖数量。
#148. 【NOIP2015】跳石头
#include<stdio.h> #include<iostream> using namespace std; int l,n,m; int a[50005]; int L; int check(int x) { int last = 0; int ans = 0; for(int i=1;i<=n;i++) { if(a[i]-last<x) ans++; else last = a[i]; } if(ans>m)return 0; return 1; } int main() { scanf("%d%d%d",&L,&n,&m); for(int i=1;i<=n;i++) scanf("%d",&a[i]); a[n+1]=L;n++; int l = 0,r = L; while(l<=r) { int mid = (l+r)/2; if(check(mid))l=mid+1; else r=mid-1; } printf("%d\n",l-1); }
原博客链接:https://www.cnblogs.com/qscqesze/p/4955270.html