Codeforces Round 995 (Div. 3)

题目链接:Problem - E - Codeforces

E. Best Price

题目描述

一批圣诞树已经运抵贝兰德最大的商店。 nn 已经有顾客来到商店,想要购买圣诞树。

在销售开始之前,商店需要确定一棵圣诞树的价格(所有顾客的价格相同)。为此,商店需要掌握每位顾客的一些信息。

对于 ii -th 顾客,已知两个整数 aiai 和 bibi ,这两个整数定义了他们的行为:

  • 如果产品价格最多为 aiai ,顾客会购买一棵树并留下好评;
  • 否则,如果产品价格最多为 bibi ,客户会购买一棵树,但会留下负面评论;
  • 否则,顾客根本不会买树。

你的任务是计算该商店可能获得的最大收益,前提是它不能收到超过 kk 的负面评论。

输入

输出

对于每个测试用例,打印一个整数--在商店收到的负面评论不超过 kk 的情况下,商店可能获得的最大收益。

input

5
2 0
2 1
3 4
1 1
2
5
3 3
1 5 2
3 6 4
4 3
2 3 2 8
3 7 3 9
3 1
2 9 5
12 14 9

output

2
5
9
14
15

思路   枚举+排序+二分

对ai,bi分别用两个数组存储,从小到大排序,枚举ai(bi)的1-n下标(在我的代码中我用一个结构体数组c[],我也就只需要枚举c[]中的x,y的值),相当于把价钱设置成为当前的ai或bi的值我们记为X,把价钱设置好后,查询ai数组中第一个>=X的下标,例如a数组中的数是1 3 5 7 我们X假设是3,那么3下标以前的数都会被投诉,毕竟价钱超出了预期。也就是被投诉的值是查询到下标-1,先令为cnt=(id1-1)但这不一定都是投诉后购买的,要是价钱超过bi,顾客就不会购买,因此在数组b中查询>=X的值,假设数组b对值为 1 4 7 9  查找到下标id2=2,id2-1的值就是顾客拒绝购买,最后的投诉条数总共是cnt-=(id2-1),要是cnt>k,不符合条件,反之比较保存,哪一次的价格设置的收益最大。

AC代码

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long 
int t,n,a[200020],b[200020],l,r,k,maxx,cnt,res;
struct node{
	int x;
	int y;
}c[200010];
void solve2(int query)
{
	cnt=0;
	int id1=lower_bound(a+1,a+n+1,query)-a;
//	拒绝的人
	if(id1!=-1) cnt=id1-1;
		
//	直接不购买的人 
	int id2=lower_bound(b+1,b+n+1,query)-b;
	
//	拒绝的人-不购买的人才是给差评的条数 
	if(id2!=-1) cnt-=id2-1;
	
//	给差评信息条数超过k不用计算了 
	if(cnt>k) return ; 
	
	res=max(res,(n-id2+1)*query);
}
void solve()
{ 
    cin>>n>>k;
    for(int i=1;i<=n;i++)
    {
    	cin>>c[i].x;
    	a[i]=c[i].x;
	}
	for(int i=1;i<=n;i++)
	{
		cin>>c[i].y;
		b[i]=c[i].y;
	}
	sort(a+1,a+n+1);
	sort(b+1,b+n+1);
	
	for(int i=1;i<=n;i++)
	{
		solve2(c[i].x);
        solve2(c[i].y);
	}
} 
signed main()
{
	cin>>t;
	while(t--)
	{
		solve();
		cout<<res<<endl;
		res=0;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值