(两道二分标致题)(洛谷 1182 1316)数列分段Section II 丢瓶盖
2018-01-21 09:10
501 查看
今天就稍微讲一下二分
二分主要就是运用于查找,最小值最大和最大值最小其中后面两种就是我们今天要讲的。(二分答案)
伪代码
while (l<=r){int mid=(l+r)>>1;
if (check(mid)) l=mid+1;
else r=mid-1;
}
当最小值最大时输出r否则输出l
然后其实最重要的是初值和检验
首先就是数列分段Section II(最大值最小)
这道题其实就是给你一些数,分成m段,最大的和最小于是首先初值为l=max(a[i]),r=
然后初始化部分如果能合并就尽量合并,所以
代码如下
#include <cstdio> #include <algorithm> using namespace std; int a[100001],l,r,n,m; bool check(int num){ int sum=0,tot=0; for (int i=1;i<=n;i++){ if (sum+a[i]<=num) sum+=a[i];//能合并就合并 else sum=a[i],tot++;//否则分段 } return tot>=m;//不少于m段吗 } int main(){ scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) scanf("%d",&a[i]),l=max(l,a[i]),r+=a[i]; while (l<=r){ int mid=(l+r)>>1; if (check(mid)) l=mid+1; else r=mid-1; } printf("%d",l); }
下一题丢瓶盖
选m个瓶盖,使距离最小的最大。还是一样的方法
初值l=min(a[i]-a[i-1])(距离最小值)r=a
-a[1] (距离最大值)
然后检查部分;如果它符合距离分了不少于m-1段那么返回真.
#include <cstdio> #include <algorithm> #define A ((1<<30)-1)*2+1 using namespace std; int l=A,n,m,r,a[100001]; bool check(int mid){ int s=0,bit=a[1]; for (int i=2;i<=n;i++){ if (a[i]-bit>=mid) s++,bit=a[i]; if (s>=m) return true; } if (s+1<m) return false; else return true; } int main(){ scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) scanf("%d",&a[i]); sort(a+1,a+1+n); r=a -a[1]; for (int i=2;i<=n;i++) l=min(l,a[i]-a[i-1]); while (l<=r){ int mid=(l+r)>>1; if (check(mid)) l=mid+1; else r=mid-1; } printf("%d",r); return 0; }
相关文章推荐
- |洛谷|二分|P1182 数列分段Section II
- 洛谷1182 数列分段Section II
- 洛谷 P1182数列分段Section II
- 洛谷 P1182 数列分段Section II
- 【分治】洛谷 P1182 数列分段Section II
- 洛谷 P1181,1182 数列分段Section
- 洛谷P1182 数列分段Section II
- 洛谷 P1182 数列分段Section II
- 洛谷P1182 数列分段Section II(二分)
- 洛谷OJ - P1182 - 数列分段Section II(二分答案)
- 洛谷 P1181 数列分段Section I
- P1182 数列分段Section II
- P1182 数列分段Section II
- 洛谷 P1181 数列分段Section I
- 洛谷 1181——数列分段Section I(贪心)
- 洛谷 P1181 数列分段Section I
- [luoguP1316] 丢瓶盖(二分答案)
- P1182 数列分段Section II
- 洛谷:P1182:数列分段`Section II`
- 洛谷P1181 数列分段Section I