前言
传送门 :
题意 :
给定
n
n
n个包裹,两两包裹合并,其价值为两数之和除k,求合并所有包裹后得到的最大价值
思路 :
先考虑不合并,那么每个包裹提供的价值就是
a
[
i
]
/
k
a[i]/k
a[i]/k
然后我们贪心的考虑合并,对这些包裹取余将其装到桶的,双指针的找到 能匹配的 和 自己和自己的
code :
int a[N],cnt[N];
int n,k;
void solve(){
ll res = 0;
cin>>n>>k;
for(int i=1;i<=n;i++){
cin>>a[i];
cnt[a[i]%k]++;//桶存放
res += a[i]/k;
}
int sum = 0;
for(int i=1 , j = k-1 ;i<=j ;i ++ ,j -- ){
sum += cnt[j];
if(i == j) break;
//被少的那个约束
int t = min(sum,cnt[i]);
res +=t;
sum -=t;
}
// /2是因为 每组两个
cout<<res+sum/2<<endl;
for(int i=1;i<=n;i++) cnt[a[i]%k] -- ;//清空
}
int main(){
int t;cin>>t;while(t--)
solve();
return 0 ;
}