[Ybt OJ] [Basic Algorithm Chapter 3] Bisection Algorithm

「 「 Basic Algorithm」」" No.3 33 Chapter dichotomy algorithm
catalog:

A.数列分段
B.防具布置
C.最大均值

A . A. A . Example111 sequence segment

Luo Gu link linklink
Insert picture description here

analysis:

You can save the space of the prefix and then consider a greedy, go to the dichotomy, if you
can add, if you can’t, you can accumulate the number of segments and finally judge that the number of segments is not less than mmm is enough. Thesum
with the sameprefixisO (n) O(n)O ( n ) complexity

CODE:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=1e5+5;
int n,m,a[N],l,r;
bool check(int x)
{
    
    
	int cnt=1,sum=0;
	for(int i=1;i<=n;i++)
	{
    
    
		if(sum+a[i]<=x) sum+=a[i];  //贪心
		else cnt++,sum=a[i];
	}
	return cnt<=m;
}
void work()
{
    
    
	while(l<r)  //二分
	{
    
    
		int mid=(l+r)>>1;
		if(check(mid)) r=mid;
		else l=mid+1;
	}
}
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];
	}
	work(); 
	printf("%d",l);
	
	return 0;
} 

B . B. B . Example222 armor arrangement

Insert picture description here
Insert picture description here

analysis:

Establish awai awa_ia w aiMeans 0 00~ i i How many armors are there in the position of i , just useclassification to discuss thecomplexityO (n) O(n)O ( n )
awai awa_ia w aiCan be calculated
if 2 31 − 1 2^{31}-1231If 1 is an even number, the entire line of defense hasno flaws.
If the flawpositioniskkk sokkk has theoddnumber positions are other armoreven-armor
ifawak awa_ka w akAn odd ans ansa n s must bemid midmid m i d mid m i d before sor = midr=midr=mid
a w a k awa_k a w akAn even ans ansa n s is atmid midAfter m i d ,l = mid + 1 l = mid+1l=mid+1

CODE:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define reg register 
using namespace std;
typedef long long ll;
struct node{
    
    
	ll s,e,d;
}a[200005];
ll T,n,MAX=(1<<31)-1,l,r,mid;
ll awa(ll x)
{
    
    
	ll ans=0;
	for(reg int i=1;i<=n;i++)
	{
    
    
		if(a[i].s>x) continue;
		ans+=(min(x,a[i].e)-a[i].s)/a[i].d+1;  //求防具数量
	}
	return ans;
}
void print()
{
    
    
	if(awa(MAX)%2==0){
    
    
		puts("There's no weakness.");  //没有破绽
		return;
	}else{
    
    
		printf("%d %d\n",l,awa(l)-awa(l-1));
		return;
	}
}
void work()
{
    
    
	l=0,r=MAX;
	while(l<=r)
	{
    
    
		mid=(l+r)>>1;
		if(awa(mid)%2==0) l=mid+1;  //二分
		else r=mid-1;
	}
}
int main(){
    
    
	scanf("%lld",&T);
	while(T--)
	{
    
    
		scanf("%lld",&n);
		for(reg int i=1;i<=n;i++)
			scanf("%lld%lld%lld",&a[i].s,&a[i].e,&a[i].d);
		work();
		print();
	}
	
	return 0;
} 

C . C. C . Example333 maximum mean

Insert picture description here

analysis:

Half the average of the total number obtained by subtracting the average value of the prefix and
the decimal binary adding a direct each small fractional can
then updates max maxm a x prefix sumand each time with newsumi − L sum_{iL}sumiLmin minm i n

CODE:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define reg register 
using namespace std;
typedef long long ll;
typedef double db;
const int N=1e5+5;
const db add=1e-6;
int ans,n,k;
db a[N],sum[N],l,r,mid;
bool check(db x)
{
    
    
	db minn=1e8,res=-1e8;
	memset(sum,0,sizeof(sum));
	for(reg int i=1;i<=n;i++)
		sum[i]=sum[i-1]+a[i]-x;  //前缀和
	for(reg int i=k;i<=n;i++)
	{
    
    
		minn=min(minn,sum[i-k]);
		res=max(res,sum[i]-minn);  //更新答案
	}
	return res>=0;
}
int main(){
    
    
	scanf("%d%d",&n,&k);
	for(reg int i=1;i<=n;i++)
		scanf("%lf",&a[i]);
	l=0;r=2000;
	while(l+add<r)  //二分
	{
    
    
		db mid=(l+r)/2;
		if(check(mid)) l=mid;
		else r=mid;
	}
	ans=int(r*1000);
	printf("%d",ans);
	
	return 0;
} 

Guess you like

Origin blog.csdn.net/dgssl_xhy/article/details/112131442