P9562 [SDCPC 2023] Matching

题目描述

给定长度为 nnn 的整数序列 a1,a2,⋯ ,ana_1, a_2, \cdots, a_na1,a2,,an,我们将从该序列中构造出一张无向图 GGG。具体来说,对于所有 1≤i<j≤n1 \le i < j \le n1i<jn,若 i−j=ai−aji - j = a_i - a_jij=aiaj,则 GGG 中将存在一条连接节点 iiijjj 的无向边,其边权为 (ai+aj)(a_i + a_j)(ai+aj)

GGG 的一个匹配,使得该匹配中所有边的边权之和最大,并输出最大边权之和。

请回忆:无向图的匹配,指的是从该无向图中选出一些边,使得任意两条边都没有公共的节点。特别地,不选任何边也是一个匹配。

输入格式

有多组测试数据。第一行输入一个整数 TTT 表示测试数据组数。对于每组测试数据:

第一行输入一个整数 nnn2≤n≤1052 \le n \le 10^52n105)表示序列的长度。

第二行输入 nnn 个整数 a1,a2,⋯ ,ana_1, a_2, \cdots, a_na1,a2,,an−109≤ai≤109-10^9 \le a_i \le 10^9109ai109)表示序列。

保证所有数据中 nnn 之和不超过 5×1055 \times 10^55×105

输出格式

每组数据输出一行一个整数,表示匹配的最大边权之和。

【样例解释】

对于第一组样例数据,最优方案是选择连接节点 333555,节点 444777,以及节点 888999 的三条边,边权之和为 (5+7)+(6+9)+(1+2)=30(5 + 7) + (6 + 9) + (1 + 2) = 30(5+7)+(6+9)+(1+2)=30

对于第二组样例数据,由于每条边的边权都是负数,因此最优匹配不应该选择任何边,答案为 000

对于第三组样例数据,由于图中不存在任何边,因此答案为 000

输入输出样例 #1

输入 #1

3
9
3 -5 5 6 7 -1 9 1 2
3
-5 -4 -3
3
1 10 100

输出 #1

30
0
0

C++实现

#include<bits/stdc++.h>
#define int long long
using namespace std;
int t;
int n,ans;
unordered_map<int,vector<int> >mp;
void solve(){
	mp.clear();
	n=ans=0;
	cin>>n;
	for(int i=1;i<=n;++i){
		int x;
		cin>>x;
		mp[i-x].emplace_back(x);
	}
	for(auto&p:mp){
		vector<int>vec=p.second;
		reverse(vec.begin(),vec.end());
		for(int i=0;i+2<=vec.size();i+=2){
			int sm=vec[i]+vec[i+1];
			if(sm<=0)break;
			ans+=sm;
		}
	}
	cout<<ans<<'\n';
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin>>t;
	while(t--){
		solve();
	}
	return 0;
}

在这里插入图片描述

后续

接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐