题解:P13457 [GCJ 2008 #1A] Minimum Scalar Product

题目传送门

翻译一下题意:每组测试样例给定 \(x_1, x_2, ..., x_n\)\(y_1, y_2, ..., y_n\) 两个数列,需要你改变其顺序,使 \(x_1y_1 + x_2y_2 + \cdots + x_ny_n\) 最小。

由二次函数知识,我们可以想到,两个数相隔得越远,其乘积越小。然而起决定性作用的是绝对值最大的两个数。于是我想到将这两个序列排序,一个升序,另一个降序,然后对应位上相乘,取乘积之和即可。想明白后实现方式倒也显而易见了。

代码如下

#include<bits/stdc++.h>
#define ll long long
#define ri register int
using namespace std;
const int inf=0x3f3f3f3f;
const int mod=998244353;
const int N=805;
int T,n;
ll a[N],b[N];

// 我是直接开的 long long 保险
signed main()
{
	scanf("%d",&T);
	for(ri qwq=1;qwq<=T;qwq++)
	{
		ll ans=0; // 多测清空
		scanf("%d",&n);
		for(ri i=1;i<=n;i++)
		{
			scanf("%lld",&a[i]);
		}
		for(ri i=1;i<=n;i++)
		{
			scanf("%lld",&b[i]);
		}
		sort(a+1,a+1+n);
		sort(b+1,b+1+n,greater<ll>());
        // a 数组为升序,b 数组为降序。
		for(ri i=1;i<=n;i++)
		{
			ans+=a[i]*b[i];
		}
		printf("Case #%d: %lld\n",qwq,ans);
	}
	return 0;
}

感谢阅读。

posted @ 2025-10-30 16:15  Circle_Table  阅读(1)  评论(0)    收藏  举报