Day2 數對計算
阿新 • • 發佈:2020-10-23
題面如下
題目描述
給出 個二元組 。對於兩個數對 ,可以將它們合併為 。現在,你可以按照上述規則選擇數對進行合併,求最大的 ,其中 是你合併後的數對個數。
輸入格式
第一行一個整數 ,表示數對個數。
接下來 行,第 行有兩個整數 ,表示第 個數對。
輸出格式
一行一個整數,表示答案。
樣例
樣例輸入
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;
}