2021暑期牛客多校训练5

本文详细介绍了两种算法问题的解决思路:一是利用递增队列和递减队列求解数组区间极差大于给定值的区间数量;二是计算在随机分布的黑球白球箱子里,确定所有球颜色的最小期望成本。通过对问题的深入剖析,给出了AC代码,并提出了最优策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

K-King of Range

题意:

给一数组,m次询问,每次询问给定k值,问有多少个区间的极差值>k

思路:

对于区间[l,r] ,我们可以先固定右端点r,寻找离r最近的l且满足区间[l,r]极差值>k。

可以考虑在[1,r]内找最大值和最小值计算差值;若大于k,则将位于前面的值更新(下标小的更新,因为要寻找最大的l),若是最大值在前则找次大值代替最大值,若是最小值在前则找次小值代替最小值并重复该步骤,直到差值不大于k

可以用递增队列和递减队列来实现,队列存放a数组的下标。
遍历右端点r(从2开始),将r分别加入到递增队列和递减队列中,再遍历递增递减队列中位于r前面的值并更新l值;

AC代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define rep1(i,a,b) for(int i=a;i<b;i++)
#define pre(i,a,b) for(int i=a;i>=b;i--)
#define pre1(i,a,b) for(int i=a;i>b;i--)
#define pep(i,stl) for(auto i:stl)
#define INF 0x7fffffff
#define eps 1e-6
#define fi first
#define se second
#define pb push_back
#define debug(x)   cout<<x<<endl
#define mem(a,b) memset((a),(b),sizeof(a))
const int mod=1000000007;
const double PI = acos(-1);
typedef double db;
#define pep(i,stl) for(auto i:stl)
const int N = 2e6+5;
int n,m,arr[N],add[N],de[N],cnt;
ll ans;
//map<int,int>mp;
int main() {
	cin>>n>>m;
	rep(i,1,n) scanf("%d",&arr[i]);
	while(m--){
		int k;
        ans=0;cnt=0;
		cin>>k;
		int lad=1,rad=1,lde=1,rde=1;
		add[lad]=1;de[lde]=1;
		rep(i,2,n){
			while(lad<=rad and arr[add[rad]]>arr[i]) rad--;
			add[++rad]=i;
			while(lde<=rde and arr[de[rde]]<arr[i]) rde--;
			de[++rde]=i;
			while(lde<=rde and lad<=rad and arr[de[lde]]-arr[add[lad]]>k){
				if(de[lde]<add[lad])
				cnt=de[lde],lde++;
				else
				cnt=add[lad],lad++;
			}
			ans+=cnt;
		}
		cout<<ans<<endl;
	}
	return 0; 
}

B-Boxes

题意:

n个箱子中装着黑球或白球(概率各为1/2),打开箱子的代价为 w i w_i wi,可以花费C来得到剩余未打开的箱子中黑球的个数。问要确定所有箱子内球的颜色所要花费的代价的数学期望最小是多少?

思路:

首先花费C来得知黑球的数量,然后通过开一定数目的箱子,来确定所有球的颜色

为了使代价最小,每次先开代价小的箱子,所以将箱子按代价从小到大排序

假设开0个箱子,费用为0;

开1个箱子,费用为 w 1 w_1 w1,概率为 1 2 n − 1 1\over2^{n-1} 2n11;(代价最小的箱子内装的球的颜色和其他箱子里球的颜色不同,共2中情况;n个球总共有 2 n 2^n 2n种情况)

开2个箱子,费用为 w 1 + w 2 w_1+w_2 w1+w2,概率为 1 2 n − 2 1\over2^{n-2} 2n21(前两个箱子有 2 2 2^2 22种情况,后n-2个箱子与最后开的箱子颜色肯定不同,因为只有将一种颜色的球全部取完了才能确定其他球的颜色即后n-2个箱子与前两个箱子的情况一一对应,所以共有4种情况;n个球总共有 2 n 2^n 2n种情况)

开m个箱子,费用为 ∑ i = 1 m w i \sum_{i=1}^m w_i i=1mwi,概率为 1 2 n − m 1\over2^{n-m} 2nm1

开n-1个箱子,费用为 ∑ i = 1 n − 1 w i \sum_{i=1}^{n-1} w_i i=1n1wi,概率为 1 2 1\over2 21

数学期望为 C + 1 2 n − 1 ∗ ( w 1 ) + 1 2 n − 2 ∗ ( w 1 + w 2 ) + . . . + 1 2 ∗ ( ∑ i − 1 n − 1 w i ) C+{1\over2^{n-1}}*(w_1)+{1\over2^{n-2}}*(w_1+w_2)+...+{1\over2}*(\sum_{i-1}^{n-1} w_i) C+2n11(w1)+2n21(w1+w2)+...+21(i1n1wi)

最后将所求数学期望与 ( ∑ 1 n w i ) (\sum_1^n w_i) (1nwi)作比较,输出较小值。

AC代码:

 #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define rep1(i,a,b) for(int i=a;i<b;i++)
#define pre(i,a,b) for(int i=a;i>=b;i--)
#define pre1(i,a,b) for(int i=a;i>b;i--)
#define pep(i,stl) for(auto i:stl)
#define INF 0x7fffffff
#define eps 1e-6
#define fi first
#define se second
#define pb push_back
#define debug(x)   cout<<x<<endl
#define mem(a,b) memset((a),(b),sizeof(a))
const int mod=1000000007;
const double PI = acos(-1);
typedef double db;
#define pep(i,stl) for(auto i:stl)
const int N = 2e6+5;
int n,m,arr[N],add[N],de[N],cnt;
db c,w[N],sum[N],ans;
int main() {
	cin>>n>>c;
	rep(i,1,n) scanf("%lf",&w[i]);
	sort(w+1,w+1+n);
	rep(i,1,n) sum[i]=sum[i-1]+w[i];
	db t=1;
	pre(i,n,1) t/=2,ans+=sum[i-1]*t;
	if(ans+c<sum[n]) printf("%.6f",ans+c);
	else printf("%.6f",sum[n]);
	return 0; 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值