Day2 数对计算
作者:互联网
题面如下
题目描述
给出 个二元组 。对于两个数对 ,可以将它们合并为 。现在,你可以按照上述规则选择数对进行合并,求最大的 ,其中 是你合并后的数对个数。
输入格式
第一行一个整数 ,表示数对个数。
接下来 行,第 行有两个整数 ,表示第 个数对。
输出格式
一行一个整数,表示答案。
样例
样例输入
3
5 1
3 1
3 2
样例输出
73
数据范围与提示
对于 的数据,。
对于 的数据,。
另有 的数据,。
另有 的数据,。
对于 的数据,。
题解部分
这道题的思路真的非常简单
对于二元组中任意两个数对\((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