题解 CF1399C Boats Competition
题意
给你 \(n\) 个数: \(w_1,w_2,\dots,w_n\) ,从中尽可能的选出 \(k\) 组,对于每一组 \((a_i,b_i)\) 满足 \(a_1+b_1 = a_2 + b_2 = \dots = a_k+b_k = s\) 。输出 \(k\) 。
分析
我们可以看到数据范围
\(n ( 1 \le n \le 50 )\) ,\(w_1, w_2, \dots, w_n(1 \le w_i \le n )\)
也就是说,\(s\) 最大为 \(100\) 。我们暴力枚举 \(s\) 然后找到答案就可以了。
代码
具体细节见注释。
// 头文件、快读快写自行脑补
#define re(x) read(x)
#define mes(x) memset(x,0,sizeof(x))
const int MAXN = 60;
int n,a[MAXN],tong[MAXN<<1];
// a : 原数组 , tong: 记录每个元素出现次数
int work(int x){
int res = 0;
// res : 当前情况下可以选的个数
//为了防止重复计算,限定枚举范围为前一半,注意对于x为奇数的枚举范围(lim)。
int lim = x/2;
if(x &1) lim++;
for(int i = 1;i < lim;i++)
if(tong[i] && tong[x-i]) res += min(tong[i],tong[x-i]);
if( x % 2 == 0) res += tong[x/2] / 2;
return res;
}
int main (){
int T;
re(T);
while(T--){
re(n);
mes(tong);
//注意清空
int ans = 0;
for(int i = 1;i <= n;i++) re(a[i]),tong[a[i]]++;
//枚举 s
for(int i = 2;i <= 2*n;i++) ans = max(ans,work(i));
write(ans);
}
return 0;
}
本博客作者:Werner_Yin(https://www.cnblogs.com/werner-yin/) ,转载时请注明出处,谢谢支持!