Codeforces Round #657 (Div. 2)C(补题)

Codeforces Round #657 (Div. 2)C(补题)_第1张图片

Codeforces Round #657 (Div. 2)C(补题)_第2张图片

题意:结婚纪念日到了,给老婆买花。花有m种,每种无数个。你要买n朵。第i种花的第一朵给你老婆ai的愉悦值,第二朵开始则是bi的愉悦值。你想让老婆愉悦值最高,求最高的方案。

分析:哭了,这题我赛后看了三分钟就想到思路了。为什么赛中我不看题。其实这场比赛就a题比较不正常的卡我(其实是我zz了)

首先我们要明确一个事实,这也是题目最重要的隐藏信息:买多种花的话最多只会买一种。因为如果买了两种就意味着要么是相等(可以买一种),要么不相等,那肯定有更优的解。因此只可能买一种。

既然如此,策略就很清晰了。首先造一个结构体,元素是int happy;int ab;int i;int ans=-1;分别代表带来的幸福值,是a还是b(0代表a,1代表b),在原数组中的位置在哪里(方便定位另一个元素的位置),加上一个下文要用的值。

定义一个数组flag。初始值是0,如果显示1代表ai已经取过了。

然后将所有ai和bi全部处理成结构体模式。然后按照happy的大小从大到小排序。排序完成后依次处理。int tmp=0;如果是ai,tmp+=ai,ans=tmp;n--;直接往下,将ai对应的下标标记为1.如果是bi,如果对应的ai已经取过,ans=tmp+n*bi;否则ans=tmp+ai+(n-1)*bi。

最后直接找最大的ans即可。

代码:

#include
using namespace std;
typedef long long ll;
const int N=1e5+5;
ll n,m; 
ll a[N],b[N];
ll flag[N];
struct Shu
{
	ll happy;
	ll ab;
	ll pos;
	ll ans;
}shu[2*N];
bool cmp(Shu x,Shu y)
{
	return x.happy>y.happy;
}
void rlmn()
{
	scanf("%lld%lld",&n,&m);
	for (int i=0;ires)
		{
			res=shu[i].ans;
		}
	}
	printf("%lld\n",res);
}

int main()
{
	int T;
	scanf("%d",&T);
	while(T--)rlmn();
	return 0;
}

wa点:

1.没有考虑n减着减着<=0了,就会造成买负花。

2.一开始没有考虑到每种花买一朵的特殊情况,只在bi处结算,没在ai处结算

你可能感兴趣的:(算法训练)