标签:uri enum continue ems https include 暴力 += lse
[https://codeforces.com/contest/557/problem/C]
给你每个木棍的长度,以及移除每个木棍的代价
使得桌子稳定,最长的木棍必须大于剩下的一半
这个数据范围,就是得暴力和前缀和还有一些技巧
枚举每一种长度,大于它的全部移除,
那么剩下的就尽可能地移除少量的木棍,而且移除可以移除的最小代价
复杂度2e7左右。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
struct str{
int l,d;
}a[maxn];
int num[maxn];//长度为i的数量
int prenum[maxn];//长度小于等于i的有多少个
int s[maxn];// 第i个之前全部移除需要的代价
int t[210];//当前代价为i的有多少个
bool cmp(str x,str y){
if(x.l==y.l) return x.d<y.d;
return x.l<y.l;
}
int main(){
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int n;
while(cin>>n){
memset(num,0,sizeof(num));
memset(prenum,0,sizeof(prenum));
memset(s,0,sizeof(s));
memset(t,0,sizeof(t));
for(int i=1;i<=n;i++)
{
cin>>a[i].l;
num[a[i].l]++;
}
for(int i=1;i<=n;i++)
cin>>a[i].d;
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++)
s[i]=s[i-1]+a[i].d;
for(int i=1;i<=100000;i++)
prenum[i]=prenum[i-1]+num[i];
int ans=1e9;
for(int i=1;i<=100000;i++)
{
if(!num[i]) continue;
int tem=prenum[i]-(2*num[i]-1);//该移除的个数
int cur=s[n]-s[prenum[i]];
//cout<<i<<' '<<tem<<' '<<cur<<endl;
for(int j=1;j<=200&&tem>0;j++)
{
if(tem>=t[j]){
tem-=t[j];
cur+=t[j]*j;
}
else {
cur+=tem*j;
tem=0;
}
}
ans=min(ans,cur);
for(int j=prenum[i-1]+1;j<=prenum[i];j++)
t[a[j].d]++;
}
cout<<ans<<endl;
}
return 0;
}
标签:uri enum continue ems https include 暴力 += lse
原文地址:https://www.cnblogs.com/mch5201314/p/10982289.html