[题解]洛谷P4653

[题解]洛谷P4653

原题链

大体算法

我们可以发现,点亮权值越大的灯泡一定比点亮权值小的灯泡优(显然),所以我们肯定从最大的开始连续地取,那么我们先将权值从大到小排个序,接下来先考虑暴力算法,就是枚举\(a\)数组取到第\(i\)位,\(b\)数组取到第\(j\)位,并且暴力统计答案,这是我们发现每次统计到第\(i\)\(j\)为其实就是\(a.b\)数组的前缀和,这样我们就可以优化一下,但仍然不是满分
接着我们想,由于最终的答案是取\(a.b\)两组的最小值,所以如果\(a\)数组的答案和\(b\)数组的答案这两个答案差距太大显然是不优的,因为反正是取最小值,所以不如把大的那部分少取一点,花费还更少,其实我们已将正解得出:那就是\(a.b\)数组的两个答案应该要尽量的接近,所以分两次做,其实也是暴力,第一次从\(1~n\)枚举\(a\)数组的前缀和\(suma[i]\),并用\(lower_bound\)查询比\(suma[i]\)大的最小的\(sumb[j]\),并统计答案,再暴力枚举\(sumb\)即可.

代码

#include <bits/stdc++.h>
using namespace std;
double a[1000010],b[1000010];
double suma[1000010],sumb[1000010];
bool cmp(double x,double y){
	return x > y;
}
int main(){
	freopen("coin.in","r",stdin);
	freopen("coin.out","w",stdout);
	int n;
	scanf("%d",&n);
	for(int i = 1;i <= n;i++)
		cin>>a[i];
	for(int i = 1;i <= n;i++)
		cin>>b[i];
	sort(a + 1,a + n + 1,cmp);sort(b + 1,b + n + 1,cmp);
	suma[1] = a[1];sumb[1] = b[1];
	for(int i = 2;i <= n;i++){
		suma[i] = a[i];
		sumb[i] = b[i];
		suma[i] += suma[i - 1];
		sumb[i] += sumb[i - 1];
	}
	double ans1 = 0.0,ans2 = 0.0;
	for(int i = 1;i <= n;i++){
		int tmp1 = suma[i];
		int p = lower_bound(sumb + 1,sumb + n + 1,tmp1) - sumb;
		ans1 = max(ans1,min(suma[i],sumb[p]) - i - p);
	}
	for(int i = 1;i <= n;i++){
		int tmp1 = sumb[i];
		int p = lower_bound(suma + 1,suma + n + 1,tmp1) - suma;
		ans2 = max(ans2,min(sumb[i],suma[p]) - i - p);
	}
	printf("%.4lf\n",max(ans1,ans2));
	return 0;
}
posted @ 2020-11-02 20:52  czyczy  阅读(106)  评论(0编辑  收藏  举报