其他分享
首页 > 其他分享> > Day2 数对计算

Day2 数对计算

作者:互联网

题面如下

题目描述

给出 n 个二元组 (a_i,b_i) 。对于两个数对 (a_i,t),(a_j,t) ,可以将它们合并为 (a_i+a_j,t) 。现在,你可以按照上述规则选择数对进行合并,求最大的 \sum_{i=1}^ma_i^2 ,其中 m 是你合并后的数对个数。

输入格式

第一行一个整数 n ,表示数对个数。
接下来 n 行,第 i 行有两个整数 (a_i,b_i) ,表示第 i 个数对。

输出格式

一行一个整数,表示答案。

样例

样例输入

3
5 1
3 1
3 2

样例输出

73

数据范围与提示

对于 10\% 的数据, n=1
对于 30\% 的数据, n\le 1000
另有 20\% 的数据, a_i=1
另有 30\% 的数据, b_i\le 1000
对于 100\% 的数据, 1\le n\le 10^5,1\le a_i\le 10^4,1\le b_i\le 10^9

题解部分

这道题的思路真的非常简单
对于二元组中任意两个数对\((a_i,t)\),$(a_j,t),为了让 \(\sum^{m}_{i=1}{a_i^2}\) 最大,我们必须合并所有可以合并的数对。证明如下:
若数对一为\((a,t)\),数对二为\((b,t)\)。若a,b未合并,二者和为:\(a^2+b^2\)。若二者合并,则值为:\((a+b)^2\)。
因为:
\(a>0,b>0.(a+b)^2=a^2+2ab+b^2\)
所以:
\((a+b)^2>a^2+b^2\)
由此可证明我们的思路正确。
接下来就没什么难的了,代码实现如下:

#include<bits/stdc++.h>
#define ll long long
const int N=1e6+10;
using namespace std;
struct dui
{
	ll a;
	ll z;
}arr[N];
dui hou[N];
ll n;
ll ans;
ll cnt;
bool cmp(dui mm,dui nn)
{
	return mm.z<nn.z;
}
int main()
{
	freopen("expedition.in","r",stdin);
	freopen("expedition.out","w",stdout);
	cin>>n;
	for(ll i=1;i<= n;i++)
	{
		cin>>arr[i].a>>arr[i].z;
	}
	sort(arr+1,arr+n+1,cmp);
	for(ll i=1;i<=n;i++)
	{
		if(arr[i].z==arr[i-1].z)
		{
			hou[cnt].a+=arr[i].a;
		}
		if(arr[i].z!=arr[i-1].z)
		{
			cnt++;
			hou[cnt].a+=arr[i].a;
		}
	}
	for(ll i=1;i<=cnt;i++)
	{
		ans+=hou[i].a*hou[i].a;
	}
	cout<<ans<<endl;
	return 0;
}

标签:10,arr,le,dui,ll,数对,Day2,计算
来源: https://www.cnblogs.com/Antima/p/13864937.html