题解: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;
}
感谢阅读。
本文来自博客园,作者:Circle_Table,转载请注明原文链接:https://www.cnblogs.com/Circle-Table/articles/19177426

浙公网安备 33010602011771号