蒟蒻求助二分
查看原帖
蒟蒻求助二分
128591
Refined_heart楼主2020/10/24 11:08
#include<bits/stdc++.h>
using namespace std;
int n,a,b,numa[50001],numb[50001];
const double eps=1e-10;
double dp[5001],p[5001],q[5001];
void check2(double va,double vb){
	for(int i=1;i<=n;++i){
		dp[i]=dp[i-1];numa[i]=numa[i-1];numb[i]=numb[i-1];
		if(dp[i]<dp[i-1]+p[i]-va-eps){
			dp[i]=dp[i-1]+p[i]-va;
			numa[i]=numa[i-1]+1;numb[i]=numb[i-1];
		}
		if(dp[i]<dp[i-1]+q[i]-vb-eps){
			dp[i]=dp[i-1]+q[i]-vb;
			numa[i]=numa[i-1];numb[i]=numb[i-1]+1;
		}
		if(dp[i]<dp[i-1]+q[i]+p[i]-va-vb-eps-p[i]*q[i]){
			dp[i]=dp[i-1]+q[i]+p[i]-q[i]*p[i]-va-vb;
			numa[i]=numa[i-1]+1;numb[i]=numb[i-1]+1;
		}
	}
}
double check(double v1){
	double l=0,r=1,mid;
	int G=50;
	while(G--){
		mid=(l+r)/2;
		check2(v1,mid);
		if(numb[n]>b)l=mid;
		else r=mid;
	}
	return l;//
}
int main(){
	scanf("%d%d%d",&n,&a,&b);
	for(int i=1;i<=n;++i)scanf("%lf",&p[i]);
	for(int i=1;i<=n;++i)scanf("%lf",&q[i]);
	double l=0,r=1,v;
	int H=50;
	while(H--){
		double mid=(l+r)/2;
		v=check(mid);
		if(numa[n]>a)l=mid;
		else r=mid;
	}
	check2(l,v);//
	printf("%.5lf\n",dp[n]+l*a+v*b);//
	return 0;
}

蒟蒻想问下,其中 check函数为什么返回的是 l 而不是r,l 不是使得numb[n]>nnumb[n]>n的最小的 mid (不符合要求)吗?以及 main 函数中的二分,为什么最后进行 dp 时要用两个二分的 l 而不是 r? r 难道不才是最后一个符合条件的 mid 吗

以及为什么手动调整二分次数时,设为55>5055>50的时候答案出错?按理说二分次数越多答案不应该越精确吗)还是说精度炸掉了)

最后输出答案的时候为什么必须乘以a,ba,b而不是 dp 后的numa,numbnuma,numb啊)

蒟蒻问题有点多)求教

2020/10/24 11:08
加载中...