社区讨论
神秘小贪心 75pts 求 hack
P6155修改参与者 2已保存回复 4
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 4 条
- 当前快照
- 1 份
- 快照标识符
- @mihk8nv7
- 此快照首次捕获于
- 2025/11/27 23:00 3 个月前
- 此快照最后确认于
- 2025/11/29 11:40 3 个月前
rt,思路是统计每种数最终会归属到多大的数,然后贪心策略 尽量让小的数往最大走,保证多取的尽量多,然后再留一些是跟上一级数的差,即不会卷进上一级里的部分,然后分别统计这两种,把 个操作次数排序,递减跟递增配对。
不知道是想假了还是写挂了,样例全过。
CPP/*
重要结论:总操作次数不变
∴多的尽量多
先排序,统计每种数的增加上限(最终最大的那个数的值)和增加下限(与下一种数的差)
*/
#include<bits/stdc++.h>
using namespace std;
constexpr int N=1000006;
unsigned n,m,a[N],f[N],tot;
unsigned long long b[N],lim[N],d[N],use[N],ans;
unordered_map<unsigned,int>cnt;
signed main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i],cnt[a[i]]++;
for(int i=1;i<=n;i++)cin>>b[i];
sort(a+1,a+1+n),sort(b+1,b+1+n);
m=unique(a+1,a+1+n)-a-1;
for(int i=m;i;i--){
f[i]=i,lim[i]=a[i]+cnt[a[i]]-1;
if(i<m&&lim[i]>=a[i+1])f[i]=f[i+1],lim[f[i]]+=lim[i]-a[i+1]+1,d[i]=a[i+1]-a[i];
else d[i]=cnt[a[i]];
}
for(int i=1;i<=m;i++){
while(cnt[a[i]]>d[i]){
use[++tot]=lim[f[i]]-a[i];
lim[f[i]]--;
cnt[a[i]]--;
}
while(d[i]--)use[++tot]=d[i];
}
sort(use+1,use+1+n);
for(int i=n;i;i--)ans+=b[i]*use[n-i+1];
cout<<ans;
return 0;
}
回复
共 4 条回复,欢迎继续交流。
正在加载回复...